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

BackgroundService重复启动问题:MyHostedService启动两次原因及自动注册疑惑

问题分析与解决方案

为什么你的MyHostedService会启动两次?

核心原因是这个服务被注册了两次:一次是你通过Autofac显式注册的,另一次是通过ASP.NET Core默认DI容器(或某个自动注册逻辑)偷偷注册的。

ASP.NET Core的Host启动时,会从DI容器中获取所有实现IHostedService的实例并逐一启动。当存在两个独立的注册项时,就会生成两个不同的服务实例(从你日志里的不同Guid也能验证这一点),自然会触发两次启动流程。

另外你用了InstancePerDependency生命周期,这个设置意味着每次解析IHostedService都会创建新实例——但如果只有一个注册项,Host解析IEnumerable<IHostedService>时只会得到一个实例。出现两次启动,必然是存在两个独立的注册来源。


为什么注释掉Autofac注册后,服务仍会被自动注册启动?

这说明你的MyHostedService被某个自动注册逻辑盯上了,常见的可能性有这些:

  • 你无意中调用了默认DI的注册方法:检查你的Program.cs或Startup.cs,是不是不小心写了builder.Services.AddHostedService<MyHostedService>()却忘了?这个方法默认会把服务注册为单例,所以注释掉Autofac的注册后,仍会有一个实例启动。
  • 约定式注册在偷偷干活:如果你的项目里有用RegisterAssemblyTypes扫描整个程序集的代码,并且搭配了AsImplementedInterfaces()或As<IHostedService>(),那么所有实现IHostedService的类型(包括你的MyHostedService)都会被自动注册。
  • 第三方库/扩展方法自动注册:某些项目依赖的扩展库可能会自动扫描并注册HostedService类型,你可以排查下项目里的扩展方法或第三方包。

解决步骤

  1. 清理重复注册:

    • 检查并移除默认DI中的AddHostedService<MyHostedService>()调用(如果有的话);
    • 检查约定式注册代码,确保不会自动注册MyHostedService为IHostedService。
  2. 修正Autofac注册的生命周期:
    HostedService本质上应该是单例的(Host会持有实例直到应用停止),InstancePerDependency完全不适合这个场景。修改你的Autofac注册代码:

    builder.RegisterType<MyHostedService>()
        .As<IHostedService>()
        .SingleInstance();
    
  3. 验证结果:
    完成上述修改后,启动应用,日志里应该只会出现一个Guid的启动记录,服务也只会启动一次。

内容的提问来源于stack exchange,提问作者Ivan-Mark Debono

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:22:35