You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core托管服务ExecuteAsync方法关机时后续代码未执行问题

原因说明
  • 核心是.NET 取消模型的标准行为导致的:当传入CancellationToken的Task.Delay收到取消信号时,会直接抛出OperationCanceledException而非正常返回,所以await Task.Delay(...)之后的代码永远不会被执行。
  • 其次BackgroundService基类的默认实现会吞掉ExecuteAsync方法抛出的OperationCanceledException,所以你既看不到异常报错,也看不到预期的控制台输出。
修复方式

只需要捕获取消异常,就能在关机时执行收尾逻辑,修改后代码如下:

public class TestBackgroundService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        System.Console.WriteLine("Executing test background service...");
        try
        {
            await Task.Delay(Timeout.Infinite, stoppingToken);
        }
        catch (OperationCanceledException)
        {
            // 程序关机触发取消时会进入该分支
            System.Console.WriteLine("WHY DOES THIS NEVER GET CALLED?");
        }
    }
}
额外注意事项
  • 所有.NET 标准库中接收CancellationToken参数的异步方法,都遵循「取消即抛出取消异常」的统一约定,不会正常返回,这是通用设计不是BackgroundService的特有问题。
  • 收尾逻辑的执行总时长不能超过.NET 主机默认的5秒关机超时,否则进程会被强制终止,收尾逻辑依然可能执行不完。
  • 如果你是直接点击控制台窗口的关闭按钮终止程序,系统会直接杀死进程不会触发托管代码的优雅关机流程,这种场景下收尾逻辑也不会执行,只有通过Ctrl+C、容器停止、系统服务停止等标准优雅关闭方式停止程序时,取消逻辑才会被触发。

内容的提问来源于stack exchange,提问作者Jordan Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:45:02