使用IHostedService时缺少依赖为何无异常或日志输出?
为什么未注册IHostedService依赖时控制台应用无任何错误输出?
你同事遇到的这个情况,核心原因有两个:
异步方法未被等待,主线程提前退出
RunConsoleAsync()是异步方法,但你的Main方法是同步的,直接调用后没有用await等待完成。主线程执行到这里就直接结束了,此时依赖注入解析失败抛出的异常还没来得及被捕获输出,应用就已经终止了。启动早期日志系统未完全就绪
依赖注入容器尝试解析FooHostedService时,会因为找不到IFooDependency的注册而抛出InvalidOperationException,但这个异常发生在应用启动的极早期——此时默认的日志配置还没完全初始化完成,就算有异常,日志系统也没办法把错误信息输出到控制台。
怎么让错误显示出来?
最简单的办法是把Main改成异步方法并等待RunConsoleAsync():
// Program.cs 修改后的代码 namespace FooNamespace { internal class Program { static async Task Main(string[] args) { var hostBuilder = Host.CreateDefaultBuilder(args) .UseConsoleLifetime() .ConfigureServices((_, services) => { services.AddHostedService<FooHostedService>(); // 补上缺失的依赖注册 // services.AddSingleton<IFooDependency, FooDependency>(); }); await hostBuilder.RunConsoleAsync(); } } }
如果不想改成异步Main,也可以用同步等待的方式让主线程等异步操作完成:
hostBuilder.RunConsoleAsync().GetAwaiter().GetResult();
这样修改后,当依赖未注册时,控制台就会输出类似下面的错误信息:
Unhandled exception. System.InvalidOperationException: Unable to resolve service for type 'FooNamespace.IFooDependency' while attempting to activate 'FooNamespace.FooHostedService'.
补充代码示例
你提供的完整代码(修正转义后):
Program.cs
namespace FooNamespace { internal class Program { static void Main(string[] args) { var hostBuilder = Host.CreateDefaultBuilder(args) .UseConsoleLifetime() .ConfigureServices((_, services) => { services.AddHostedService<FooHostedService>(); //Missing dependency //services.AddSingleton<IFooDependency, FooDependency>(); }); hostBuilder.RunConsoleAsync(); } } }
FooHostedService.cs
namespace FooNamespace { internal class FooHostedService : IHostedService { private IFooDependency FooDependency { get; } public FooHostedService(IFooDependency fooDependency) { FooDependency = fooDependency; } public Task StartAsync(CancellationToken cancellationToken) { //If the program were working, this should display a string and pause for input Console.WriteLine("Hello, world!"); Console.ReadKey(true); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } } }
内容的提问来源于stack exchange,提问作者ConnieMnemonic
相关产品推荐
相关产品推荐

