.net core Worker Service 在没有 ctrl+C 的情况下优雅地停止之前迭代 n 次
.net core Worker Service iterate n times before gracefully stop without ctrl+C
我想要实现的是 运行 一个异步任务 n 次然后优雅地完成而无需执行 ctrl+C。我相信我需要使用 IHostLifetime,因为 CancellationToken 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
方法很危险 - 它表示服务已停止,即使 base `StopAsync 尚未停止。 That's the method 这将发出服务的取消令牌信号,因此这可能会产生意想不到的后果。应该改为:
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
实现
我想要实现的是 运行 一个异步任务 n 次然后优雅地完成而无需执行 ctrl+C。我相信我需要使用 IHostLifetime,因为 CancellationToken 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
方法很危险 - 它表示服务已停止,即使 base `StopAsync 尚未停止。 That's the method 这将发出服务的取消令牌信号,因此这可能会产生意想不到的后果。应该改为:
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
实现