如何使用取消令牌停止作用域服务?
How to stop scoped service using Cancellation Token?
我正在寻找使用 Cancellation Token
停止 Scoped background service
的方法。我遵循了以下步骤:
ScopedAlertingService.cs
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);
}
}
}
}
ConsumedServiceHostedService.cs
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);
但调试器不会使用 ConsumeScopedServiceHostedService
的 stopAsync
方法。我在这里做错了什么?谢谢
您可以将 IHostedService
注入为 Singleton
然后您可以调用后台服务的停止方法。
更新:
在托管服务中,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);
}
}
}
我正在寻找使用 Cancellation Token
停止 Scoped background service
的方法。我遵循了以下步骤:
ScopedAlertingService.cs
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);
}
}
}
}
ConsumedServiceHostedService.cs
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);
但调试器不会使用 ConsumeScopedServiceHostedService
的 stopAsync
方法。我在这里做错了什么?谢谢
您可以将 IHostedService
注入为 Singleton
然后您可以调用后台服务的停止方法。
更新: 在托管服务中,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);
}
}
}