讲师中心 微信公众号
AI工具推荐 视频效率加速

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

陌晨同学_2445

陌晨同学_2445

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

|

446人浏览过

|

来源于php中文网

原创

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

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

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

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

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

BackgroundService 的 StopAsync 调用顺序与 StartAsync 相反

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

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

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

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

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

  • 如果多个 IHostedService 的 StopAsync 累计耗时超过该阈值,主机将直接调用 Environment.Exit(1) 终止进程
  • 即使某个服务的 StopAsync 还在运行,也不会被等待 —— 没有“尽力而为”机制,超时即弃
  • BackgroundService 的 base.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.Delay、HttpClient.SendAsync、Channel.Reader.ReadAsync 等)必须传入 stoppingToken
  • 长时间 CPU 密集型工作需定期手动检查 stoppingToken.ThrowIfCancellationRequested()
  • 不要在 ExecuteAsync 中 await 一个不接受 token 的第三方异步方法,除非你确认它内部可被中断
依赖管理和超时控制是实际部署中最容易出问题的地方,尤其是当多个 BackgroundService 共享状态或资源时,启动/停止顺序 + 取消传播必须显式对齐,否则关机过程不可预测。

热门AI工具

更多
Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

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

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

14866

2023.09.14

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

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

1745

2023.09.14

token怎么获取
token怎么获取

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

4137

2023.12.21

token什么意思
token什么意思

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

6301

2024.03.01

Golang channel原理
Golang channel原理

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

454

2025.11.14

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

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

639

2025.11.17

Go语言 channel用法详解
Go语言 channel用法详解

本专题整合了go语言中channel的各种使用方法,阅读专题下面的文章了解更多详细步骤。

503

2026.04.03

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

0

2026.11.05

DBeaver安全防护教程大全
DBeaver安全防护教程大全

DBeaver安全防护专题,围绕数据库连接安全、账号密码保护和访问权限管理展开,整理SSL/TLS加密连接、SSH隧道、数据库凭据保存及证书验证等配置方法,同时介绍敏感信息保护、远程连接风险和高权限账号使用等注意事项,帮助用户提高数据库日常管理的安全性。

0

2026.11.05

热门下载

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

精品课程

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn