.net 核心辅助角色服务迭代 n 次,然后在没有 ctrl+C 的情况下正常停止



我试图实现的是运行异步任务n次,然后优雅地完成,而无需执行ctrl + C。我相信我需要使用 IHostLifetime,因为 CancelToken stoppingToken 是只读

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IServiceScopeFactory _scopeFactory;
public Worker(ILogger<Worker> logger, IServiceScopeFactory scopeFactory, IHostApplicationLifetime hostApplicationLifeTime)
{
_logger = logger;
_scopeFactory = scopeFactory;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
//Running task
}
catch (Exception ex)
{
_logger.LogError(ex, "Error");
}            
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"Worker stopped at: {DateTime.Now}");
base.StopAsync(cancellationToken);
return Task.CompletedTask;
}
public override void Dispose()
{
_logger.LogInformation($"Worker disposed at: {DateTime.Now}");
base.Dispose();
}
}

关于此的文档不多

您的代码已经接受 IHostApplicationLifetime 作为其第三个服务。当您希望主机终止时,可以调用StopApplication()

不过,StopAsync方法很危险 - 它说即使基础"StopAsync"没有停止,服务也已停止。这是将指示服务的取消令牌的方法,因此这可能会产生意想不到的后果。应改为:

public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"Worker stopped at: {DateTime.Now}");
return base.StopAsync(cancellationToken);
}

或者,更好的是:

public override Task StopAsync(CancellationToken cancellationToken)
{
await base.StopAsync(cancellationToken);
_logger.LogInformation($"Worker stopped at: {DateTime.Now}");
}

当关闭期到期且服务需要立即终止时,将发出cancellationToken参数的信号。它不由BackgroundService本身使用,而是传递给覆盖StopAsync实现

最新更新