c# - 在方法覆盖中访问字典项
问题描述
我在 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>();
}
解决方案
您的问题缺少很多要点,但我相信我可以从这两行中得出问题
services.AddHostedService<Sms>();
services.AddSingleton<ISms, Sms>();
该AddSingleton
行将Sms
为您的应用程序创建单个实例,我怀疑您正在ISms
某处注入控制器并调用RegisterCustomer
.
该AddHostedService
行将创建第二个Sms 实例,并将其用作托管服务。
解决方案是将这两件事分开,并让ICustomerRepository
托管服务和控制器共享类似的东西。
请注意,如果我在这里做得很好,这将有助于使用 的详细信息编辑您的问题ISms
,包括它的使用方式以及您在哪里打电话RegisterCustomer
。
推荐阅读
- ag-grid - 当 autoGroupColumnDef 更改时,AgGridReact 组件不更新
- python - 如何使用字典语法调用函数?
- cython - Texgenpack Wrapper - 编译问题
- css - 如何正确匹配我的子元素与其父元素的边界半径
- php - 隐藏具有相同“角色”的用户的数据
- python - 我安装了 python 但我的 Scripts 文件夹是空的
- python - Discord.py purge 命令中的人员列表和已删除消息的数量
- javascript - Java 类接收 Ajax JSON 帖子为 null
- angular - 开玩笑报道中意外发现的分支
- c# - ASP.NET C#:如何正确使用 async-await 在繁重的逻辑之前显示标签?