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

ASP.NET Web API(.NET5)按CTRL+C时IHostedService的StopAsync未触发问题

问题原因
  • 你当前直接实现IHostedService时没有正确追踪后台任务的生命周期:StartAsync中Task.Factory.StartNew搭配async lambda返回的是Task<Task>类型,你直接返回外层Task后,宿主会认为托管服务启动完成,不会追踪内层实际执行业务逻辑的Task状态,应用退出时不会等待你的后台任务结束,直接就终止进程了。
  • Run方法中捕获异常/取消后直接调用_appLifetime.StopApplication(),会触发应用强制终止流程,跳过部分优雅清理逻辑。
  • 你当前的服务注册存在笔误:实现的托管服务类是MyHostedService,但注册的是CacheManagerHostedService,如果实际代码没对齐也会导致生命周期逻辑异常。
  • 你在StopAsync中输出的是Debug级别的日志,如果项目默认日志配置过滤了Debug级别,也会看不到对应输出。
需修改的内容

1. 优先继承BackgroundService抽象类实现托管服务

.NET 自带的BackgroundService已经封装了后台任务生命周期的管理逻辑,不需要自己手动处理StartAsync的线程创建、任务追踪逻辑,能避免绝大多数生命周期问题。

2. 调整后台任务逻辑,移除不必要的强制终止调用,在StopAsync中等待任务退出

修改后的托管服务代码示例:

public class MyHostedService : BackgroundService
{
    private readonly ILogger<MyHostedService> _logger;

    public MyHostedService(ILogger<MyHostedService> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            // 原来的长时间运行代码,直接用stoppingToken判断退出信号即可
            while (!stoppingToken.IsCancellationRequested)
            {
                // 你的业务逻辑
                await Task.Delay(1000, stoppingToken);
            }
        }
        catch (OperationCanceledException)
        {
            _logger.LogInformation("后台任务收到取消信号,即将退出");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "后台任务出现未处理异常");
        }
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        // 这里可以先写你的清理逻辑
        _logger.LogInformation("StopAsync开始执行,正在清理资源");
        
        // 调用基类的StopAsync,等待后台任务正常退出
        await base.StopAsync(cancellationToken);
        
        _logger.LogInformation("StopAsync执行完成");
    }
}

3. 修正服务注册逻辑

对齐注册的服务类型和实际实现类:

services.AddHostedService<MyHostedService>();

4. 验证日志配置

如果需要看到Debug级别的日志,确认appsettings.json中的日志配置没有过滤MyHostedService的Debug级别输出,测试阶段可以先把日志级别改成Information验证StopAsync是否执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:27:06