.NET 6控制台应用:如何让HostedService在主机启动后运行
解决方案
给你两个靠谱的实现思路,按需选择:
方案一:监听应用启动完成事件(最可靠)
通过IHostApplicationLifetime的ApplicationStarted事件,确保FooService的业务逻辑在所有初始化操作、其他HostedService启动完成后再执行。修改后的代码如下:
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { var builder = Host.CreateApplicationBuilder(args); // 先注册其他需要提前初始化的HostedService // builder.Services.AddHostedService<YourOtherInitService>(); builder.Services.AddHostedService<FooService>(); builder.Build().Run(); } } public class FooService : BackgroundService { readonly ILogger<FooService> _logger; readonly IHostApplicationLifetime _appLifetime; public FooService(ILogger<FooService> logger, IHostApplicationLifetime appLifetime) { _logger = logger; _appLifetime = appLifetime; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 创建信号量等待应用启动完成 var startedSignal = new TaskCompletionSource(); void OnAppStarted() => startedSignal.TrySetResult(); // 订阅启动完成事件 _appLifetime.ApplicationStarted.Register(OnAppStarted); try { // 等待事件触发或取消信号 await Task.WhenAny(startedSignal.Task, Task.Delay(Timeout.Infinite, stoppingToken)); } finally { // 取消订阅避免内存泄漏 _appLifetime.ApplicationStarted.Unregister(OnAppStarted); } // 此处即为所有初始化完成后执行的逻辑 _logger.LogInformation("FooService Executed after all initialization."); } }
原理
ApplicationStarted事件会在主机完成所有启动流程(包括所有已注册HostedService的StartAsync执行完毕)后触发,完全保证FooService是最后启动的。
方案二:控制HostedService注册顺序(适用于可控场景)
.NET Host会按照注册顺序启动HostedService,最后注册的会最后执行StartAsync。只要确保FooService是最后一个通过AddHostedService注册的服务即可:
static void Main(string[] args) { var builder = Host.CreateApplicationBuilder(args); // 先注册所有其他需要初始化的服务/HostedService builder.Services.AddHostedService<InitService1>(); builder.Services.AddHostedService<InitService2>(); // 最后注册FooService builder.Services.AddHostedService<FooService>(); builder.Build().Run(); }
注意事项
如果项目中引入了第三方库,而第三方库会自动注册HostedService,那么无法保证这些服务的注册顺序在FooService之前,这种情况下方案一更稳妥。
内容的提问来源于stack exchange,提问作者ahdung
相关产品推荐
相关产品推荐

