c# - 同时运行长任务IHosted服务并可手动开启和关闭
问题描述
嗨,我在使用 IHostedService 为我的后台服务运行长任务时遇到问题,起初它确实工作正常,但从长远来看,后台服务突然停止,此线程退出代码:
The thread 10824 has exited with code 0 (0x0).
The thread 12340 has exited with code 0 (0x0).
The thread 9324 has exited with code 0 (0x0).
The thread 11168 has exited with code 0 (0x0).
The thread 11616 has exited with code 0 (0x0).
The thread 9792 has exited with code 0 (0x0).
我将我的后台服务注册为
//Register Background
serviceCollection.AddSingleton<CoinPairBackgroundService>
serviceCollection.AddSingleton<SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<LeaderboardHoursBackgroundService>();
serviceCollection.AddSingleton<IHostedService, CoinPairBackgroundService>();
serviceCollection.AddSingleton<IHostedService, SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardHoursBackgroundService>();
因为将来我想手动打开和关闭我的后台服务
IServiceProvider provider = _serviceProvider.GetService<MyBackgroundServiceHere>();
provider.StartAsync();
provider.StopAsync
这是我在后台服务 StartAsync 中的代码
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("Leaderboard minute ranking updates is starting");
Task.Run(async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
_logger.LogDebug("Leaderboard minute ranking updates is dequeueing");
await DequeueRandomCustomers();
_logger.LogDebug("Leaderboard minute ranking updates is enqueueing");
await EnqueueRandomCustomers();
_logger.LogDebug("Leaderboard minute ranking updates thread is now sleeping");
//sleep for 1 minute
await Task.Delay(new TimeSpan(0, 0, 10));
}
});
return Task.CompletedTask;
}
如果注册后台服务有问题,我会感到困惑,因为我看到我的后台服务启动了,但从长远来看,它突然停止了,我已经摆脱了后台服务中的那些 Thread.Sleep() 希望你能帮助提前谢谢.
解决方案
无需以这种奇怪的方式管理托管服务的生命周期,appsettings.json
您reloadOnChange: true
可以IOptionsMonitor<>
在appsettings.json
. 并使用该设置作为托管服务StartAsync
方法中已启动任务的取消。并且您需要侦听重新启动服务的OnChange
事件IOptionsMonitor<>
。
appsettings.json
:
"HostedService": {
"RunService1": true
}
注册该选项,以便:
public class HostedServiceConfig
{
public bool RunService1 { get; set; }
}
services.Configure<HostedServiceConfig>(Configuration.GetSection("HostedService"));
然后在以下帮助下创建HostedService1
和注册AddHostedService
:
services.AddHostedService<HostedService1>();
这是示例StartAsync
:
public class HostedService1 : IHostedService
{
private readonly IOptionsMonitor<HostedServiceConfig> _options;
private CancellationToken _cancellationToken;
public HostedService1(IOptionsMonitor<HostedServiceConfig> options)
{
_options = options;
// Or listen to changes and re-run all services from one place inside `Configure` method of `Startup`
_options.OnChange(async o =>
{
if (o.RunService1)
{
await StartAsync(_cancellationToken);
}
});
}
public Task StartAsync(CancellationToken cancellationToken)
{
if(_cancellationToken == null)
{
_cancellationToken = cancellationToken;
}
Task.Run(async () =>
{
while (!_cancellationToken .IsCancellationRequested || !_options.CurrentValue.RunService1)
{
....
}
});
return Task.CompletedTask;
}
...
}
如果内部有任何更改appSettings.json
,您_options.CurrentValue.RunService1
将自动重新加载。
推荐阅读
- r - 如何按每日最小值聚合数据框
- cqrs - 拉戈姆 | 读取端处理器的返回值
- amazon-web-services - 如何将步骤中的输入插入到 json 结构并传递到步骤函数中的下一步?
- javascript - 向后打印特定索引的值
- android - SwipeRefreshLayout 和处理 webview 中的外部链接(手动类)在 android webview 中不能一起工作
- c - strcpy 将结构名称复制到字符数组?
- c# - Why would a non-UI thread block the UI?
- python - Python regular expression match number in string
- c# - 在 N 层项目中使用泛型的自动映射器
- excel - 简单代码在即时窗口中工作,在应用程序中生成 1004 错误