0

0

c# IHostedService 和 BackgroundService 的启动和停止顺序

月夜之吻

月夜之吻

发布时间:2026-01-24 12:29:02

|

426人浏览过

|

来源于php中文网

原创

IHostedService启动按AddHostedService注册顺序串行执行StartAsync,停止则逆序执行StopAsync;BackgroundService需在ExecuteAsync中正确传递和检查stoppingToken,否则超时将导致强制进程终止。

c# ihostedservice 和 backgroundservice 的启动和停止顺序

IHostedService 实现类的启动顺序由注册顺序决定

IServiceCollection 中调用 AddHostedService() 的先后顺序,直接决定了 IHostedService.StartAsync() 的执行顺序。ASP.NET Core 主机会按注册顺序依次 await 所有 StartAsync() 方法,**不会并发启动**。

  • 若 A 依赖 B 已初始化(比如 B 初始化了共享资源),必须先注册 B,再注册 A
  • 注册顺序不等于构造函数调用顺序 —— 构造注入仍遵循 DI 容器解析逻辑,但 StartAsync 严格按 AddHostedService 顺序串行执行
  • 任意一个 StartAsync 抛出未捕获异常,后续所有服务的 StartAsync 都不会执行,主机启动失败

BackgroundService 的 StopAsync 调用顺序与 StartAsync 相反

BackgroundServiceIHostedService 的抽象基类,它内部维护了一个 CancellationTokenSource,并在 StopAsync 中触发取消信号。但关键点在于:**所有 IHostedService.StopAsync() 按注册顺序的逆序执行**。

  • 即:最后注册的服务最先被停止(LIFO)
  • 这是为了支持“后启先停”的依赖关系:A 依赖 B 的服务,B 应该比 A 晚停,以确保 A 停止时 B 仍可用
  • BackgroundService 自动处理了循环等待其后台任务结束(通过 ExecuteAsync 返回的 Task),所以你的 StopAsync 通常只需 await base.StopAsync(),无需手动 Cancel

StopAsync 超时会导致强制终止,且不保证执行完成

主机默认给所有 StopAsync 总共 5 秒超时(可通过 IHostBuilder.UseShutdownTimeout() 修改)。这个超时是全局的,不是每个服务单独计时。

零一万物开放平台
零一万物开放平台

零一万物大模型开放平台

下载
  • 如果多个 IHostedServiceStopAsync 累计耗时超过该阈值,主机将直接调用 Environment.Exit(1) 终止进程
  • 即使某个服务的 StopAsync 还在运行,也不会被等待 —— 没有“尽力而为”机制,超时即弃
  • BackgroundServicebase.StopAsync() 会 await ExecuteAsync 返回的 Task,但如果该 Task 本身没响应取消(比如没检查 cancellationToken.IsCancellationRequested),就会拖垮整个关机流程

常见错误:在 BackgroundService.ExecuteAsync 中忽略 cancellation token

最典型的崩溃场景是:后台任务死循环且不响应取消,导致 StopAsync 卡住,最终触发主机强制退出。

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        try
        {
            // ❌ 错误:没有把 stoppingToken 传给异步操作,且循环内没检查
            await DoWork(); // 如果 DoWork 内部不响应 token,这里可能永远不返回
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Work failed");
        }
        await Task.Delay(1000, stoppingToken); // ✅ 正确:Delay 显式接受 token,能及时响应取消
    }
}
  • 所有阻塞或延迟操作(Task.DelayHttpClient.SendAsyncChannel.Reader.ReadAsync 等)必须传入 stoppingToken
  • 长时间 CPU 密集型工作需定期手动检查 stoppingToken.ThrowIfCancellationRequested()
  • 不要在 ExecuteAsync 中 await 一个不接受 token 的第三方异步方法,除非你确认它内部可被中断
依赖管理和超时控制是实际部署中最容易出问题的地方,尤其是当多个 BackgroundService 共享状态或资源时,启动/停止顺序 + 取消传播必须显式对齐,否则关机过程不可预测。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6110

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

815

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1064

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1289

2024.03.01

Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

247

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

342

2025.11.17

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

9

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

18

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号