ASP.NET Core托管服务未运行问题排查与求助
向应用中添加托管服务时遇到问题
我尝试向应用中添加Hosted Service,但它完全无法工作(调试时其任何方法都未被调用)。以下是该Hosted Service的代码:
using Data.Data; namespace Shop.HostedServices; public sealed class ChangeOrderStatusHostedService : IHostedService, IDisposable { private ApplicationDbContext? _db; private readonly IServiceScopeFactory _serviceScopeFactory; private Timer? _timer; public ChangeOrderStatusHostedService(IServiceScopeFactory serviceScopeFactory) { _serviceScopeFactory = serviceScopeFactory; } public Task StartAsync(CancellationToken stoppingToken) { _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); return Task.CompletedTask; } private void DoWork(object? state) { using var scope = _serviceScopeFactory.CreateScope(); _db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); // not important code _db.SaveChanges(); } public Task StopAsync(CancellationToken stoppingToken) { _timer?.Change(Timeout.Infinite, Timeout.Infinite); return Task.CompletedTask; } public void Dispose() { _timer?.Dispose(); } }
以下是我在Program.cs中的注册方式:
builder.Services.AddSingleton<ChangeOrderStatusHostedService>(); // here it is builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
我花费了大量时间尝试解决,但目前仅能保证项目可正常编译无异常,服务仍无法运行。
问题原因及解决方法
问题出在托管服务的注册方式上:你只是把服务注册为普通单例,但.NET不会自动启动实现IHostedService的类型,必须使用专门的托管服务注册方法。
解决步骤
将Program.cs中的注册代码替换为:
// 使用AddHostedService注册,自动将服务加入托管服务启动管道 builder.Services.AddHostedService<ChangeOrderStatusHostedService>(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
补充优化建议
你的DoWork方法中,无需将上下文赋值给类字段_db,直接在using作用域内使用即可,避免潜在的生命周期问题:
private void DoWork(object? state) { using var scope = _serviceScopeFactory.CreateScope(); var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); // not important code db.SaveChanges(); }
内容的提问来源于stack exchange,提问作者SYKO
相关产品推荐
相关产品推荐

