我正在使用 .net7 开发一个工作服务应用程序,并且我能够将其作为一个单元在 systemd 上运行。
每当发出“systemctl stop my.service”时,我希望应用程序执行一些代码以正常关闭,但它似乎立即关闭
程序.cs:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IConfiguration _config;
public Worker(ILogger<Worker> logger, IConfiguration config)
{
_logger = logger;
_config = config;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("{env} - Worker running at: {time}",_config["env"], DateTimeOffset.Now);
await Task.Delay(5000, stoppingToken);
}
_logger.LogInformation("this line is never executed after stop");
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
await base.StopAsync(stoppingToken);
_logger.LogInformation("this line is actually executed after stop");
}
}
循环内部的输出和 StopAsync 在运行时和停止期间均已成功打印,我使用以下命令来访问它:
journalctl --unit=my.service -n 50 --no-pager
循环内部的输出和 StopAsync 在运行时和停止期间均已成功打印
对,所以它正在优雅地退出。
base.StopAsync
正在取消传递给 ExecuteAsync
的令牌。这几乎总是会导致 Task.Delay
抛出 OperationCanceledException
,从而导致 ExecuteAsync
完成。
如果您希望
ExecuteAsync
中的代码始终尝试在关机期间运行,请将其放入 finally
块中。