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

.NET Core 3中如何通过依赖注入在Worker Service与WebAPI间传递公共对象

解决方案

我来帮你解决这个问题——你需要的是把StatusInfo注册为单例服务,这样Worker服务和WebAPI就能共享同一个实例,实现双向的数据交互。以下是具体的实现步骤和代码示例:

1. 注册共享状态对象

在CreateHostBuilder的ConfigureServices方法中,将StatusInfo注册为单例服务。单例模式会确保整个应用生命周期内只存在一个StatusInfo实例,Worker和WebAPI都会拿到同一个对象:

.ConfigureServices((hostContext, services) => {
    services.AddOptions();
    // 注册单例状态对象,全局共享同一实例
    services.AddSingleton<StatusInfo>();
    services.AddHostedService<Worker>();
});

2. 在Worker中注入并更新状态

修改Worker类的构造函数,通过依赖注入获取StatusInfo实例,然后在后台任务的执行逻辑中更新状态属性:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly StatusInfo _statusInfo;

    // 通过构造函数注入共享状态对象
    public Worker(ILogger<Worker> logger, StatusInfo statusInfo)
    {
        _logger = logger;
        _statusInfo = statusInfo;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var random = new Random();
        while (!stoppingToken.IsCancellationRequested)
        {
            // 模拟任务执行,更新状态信息
            _statusInfo.LastRun = DateTime.Now;
            _statusInfo.LastAdded = random.Next(1, 100);
            _statusInfo.LastUpdated = random.Next(1, 50);

            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}

3. 在WebAPI中注入并查询状态

在你的WebAPI控制器(比如健康检查专用控制器)中,同样通过构造函数注入StatusInfo,然后暴露接口返回最新的状态信息:

[ApiController]
[Route("api/health")]
public class HealthCheckController : ControllerBase
{
    private readonly StatusInfo _statusInfo;

    public HealthCheckController(StatusInfo statusInfo)
    {
        _statusInfo = statusInfo;
    }

    [HttpGet("worker-status")]
    public IActionResult GetWorkerStatus()
    {
        // 直接返回共享的状态数据
        return Ok(new {
            WorkerLastRunTime = _statusInfo.LastRun,
            LastAddedItems = _statusInfo.LastAdded,
            LastUpdatedItems = _statusInfo.LastUpdated,
            ServiceStatus = "Running"
        });
    }
}

4. 线程安全优化(可选但推荐)

由于Worker是后台线程,WebAPI是请求线程,两者会同时访问StatusInfo,为了避免多线程下的状态不一致问题,可以给StatusInfo的属性加锁:

public class StatusInfo
{
    private readonly object _lockObj = new object();
    
    private DateTime _lastRun;
    private int _lastAdded;
    private int _lastUpdated;

    public DateTime LastRun
    {
        get { lock (_lockObj) return _lastRun; }
        set { lock (_lockObj) _lastRun = value; }
    }

    public int LastAdded
    {
        get { lock (_lockObj) return _lastAdded; }
        set { lock (_lockObj) _lastAdded = value; }
    }

    public int LastUpdated
    {
        get { lock (_lockObj) return _lastUpdated; }
        set { lock (_lockObj) _lastUpdated = value; }
    }
}

这样就能实现Worker和WebAPI之间的状态共享了——Worker更新的状态会实时同步到WebAPI可以读取的实例中,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:52:35