我正在寻找一种使用 Scoped background service
停止 Cancellation Token
的方法。我按照以下步骤操作:
namespace BackgroundTasksSample.Services
{
internal interface IScopedAlertingService
{
Task DoWork(System.Threading.CancellationToken stoppingToken);
}
public class ScopedAlertingService : IScopedAlertingService
{
private int executionCount = 0;
private readonly ILogger _logger;
public ScopedAlertingService(ILogger<ScopedAlertingService> logger)
{
_logger = logger;
}
public async Task DoWork(System.Threading.CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
executionCount++;
_logger.LogInformation(
"Alert: Scoped Processing Service is working. Count: {Count}", executionCount);
}
}
}
}
namespace BackgroundTasksSample.Services
{
public class ConsumeScopedServiceHostedService : BackgroundService
{
private readonly ILogger<ConsumeScopedServiceHostedService> _logger;
public ConsumeScopedServiceHostedService(IServiceProvider services,
ILogger<ConsumeScopedServiceHostedService> logger)
{
Services = services;
_logger = logger;
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
_stoppingCts.CancelAfter(30000);
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(10000, stoppingToken);
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedAlertingService>();
await scopedProcessingService.DoWork(stoppingToken);
}
}
}
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedAlertingService>();
await scopedProcessingService.DoWork(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is stopping.");
await Task.CompletedTask;
}
}
}
我正在使用 IServiceCollection
#region snippet2
services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<IScopedAlertingService, ScopedAlertingService>();
#endregion
我使用以下代码在 30 秒后停止服务:
CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
_stoppingCts.CancelAfter(30000);
但是调试器不会去 stopAsync
的 ConsumeScopedServiceHostedService
方法。我在这里做错了什么?谢谢
答案 0 :(得分:1)
您可以将 IHostedService
注入为 Singleton
,然后您可以在后台服务中调用 stop 方法。
更新: 在托管服务中,stopasync 仅在应用程序关闭时调用,但在您的代码中您可以使用它并且它可以工作:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
CancellationTokenSource _stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
_stoppingCts.CancelAfter(30000);
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
while (!_stoppingCts.Token.IsCancellationRequested)
{
await Task.Delay(10000, _stoppingCts.Token);
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedAlertingService>();
await scopedProcessingService.DoWork(_stoppingCts.Token);
}
}
}