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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:33:26