运行一个长任务IHosted服务同时可以手动开启关闭
Running a long task IHosted service at the same time and can manually turned on and off
您好,我在使用 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
方法中启动任务的取消。并且您需要监听 IOptionsMonitor<>
的 OnChange
事件以重新启动服务。
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
将自动重新加载。
您好,我在使用 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
方法中启动任务的取消。并且您需要监听 IOptionsMonitor<>
的 OnChange
事件以重新启动服务。
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
将自动重新加载。