0

我在 webapi 中有以下类,它添加到字典中,但是每次触发 checkstatus 方法(使用 Task.Delay)时,它都说字典为空。这是因为它在不同的线程上运行吗?我应该改用并发字典吗?

internal class Sms : smsBase
{
    private const int CheckFrequencyMilliseconds = 1000;
    private Dictionary<CustomerDetails, decimal> _registeredCustomers;

    public Sms(ILogger<Sms> logger)
        : base(TimeSpan.FromMilliseconds(CheckFrequencyMilliseconds), logger)
    {
        _registeredCustomers = new Dictionary<CustomerDetails, decimal>();
    }

    protected override Task CheckStatus()
    {

        foreach (var rc in _registeredCustomers)
        {
         //do something
        }

        return Task.CompletedTask;
    }

    public Task RegisterCustomer(CustomerDetails customer)
    {
        _registeredCustomers.Add(customer, 1);
        return Task.CompletedTask;
    }
}

基类代码如下。

public abstract class smsBase : BackgroundService
{
    private readonly TimeSpan _tickFrequency;
    private readonly ILogger<smsBase> _logger;

/// <inheritdoc />
/// <param name="tickFrequency">Frequency that the service will execute the CheckStatus method.</param>
protected smsBase (TimeSpan tickFrequency,ILogger<smsBase> logger)
{
  this._tickFrequency = tickFrequency;
  this._logger = logger;
}

/// <inheritdoc />
protected override sealed async Task ExecuteAsync(CancellationToken stoppingToken)
{
  this._logger.LogInformation("Service is starting.");
  while (!stoppingToken.IsCancellationRequested)
  {
    ConfiguredTaskAwaitable configuredTaskAwaitable;
    try
    {
      configuredTaskAwaitable = this.CheckStatus().ConfigureAwait(false);
      await configuredTaskAwaitable;
    }
    catch (Exception ex)
    {
      this._logger.LogError(ex, "An exception was thrown whilst checking registered strategies.");
      throw;
    }
    configuredTaskAwaitable = Task.Delay(this._tickFrequency, stoppingToken).ConfigureAwait(false);
    await configuredTaskAwaitable;
  }
  this._logger.LogInformation("Service is stopping.");

protected abstract Task CheckStatus();
}

下面是启动cs

    public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddSwaggerGen(options => {
                options.SwaggerDoc("v1", new Info() { Title = "Customers.WebApi", Version = "v1" });
            })
            .AddMvc(options => {
                options.Filters.Add(new ExceptionFilter());
                options.Filters.Add(new ProducesAttribute("application/json"));
            })
            .AddJsonOptions(options => {
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

        services.AddHostedService<Sms>();
        services.AddSingleton<ISms, Sms>();
    }
4

1 回答 1

2

您的问题缺少很多要点,但我相信我可以从这两行中得出问题

services.AddHostedService<Sms>();
services.AddSingleton<ISms, Sms>();

AddSingleton行将Sms为您的应用程序创建单个实例,我怀疑您正在ISms某处注入控制器并调用RegisterCustomer.

AddHostedService行将创建第二个Sms 实例,并将其用作托管服务。

解决方案是将这两件事分开,并让ICustomerRepository托管服务和控制器共享类似的东西。


请注意,如果我在这里做得很好,这将有助于使用 的详细信息编辑您的问题ISms,包括它的使用方式以及您在哪里打电话RegisterCustomer

于 2019-09-23T14:24:20.143 回答