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

带数据库连接的Fire and Forget模式与Hangfire该如何选型?

现有后台任务方案可行性及是否需切换至Hangfire

我们有一批需在网关执行的任务,用户发起的新排队任务会写入数据库,由BackgroundService每30秒触发并执行RunJobManager()方法:

public async Task RunJobManager()
{
    // This context is in the scope of the JobManager
    // Get a list of IDs of only gateways with an active job
    var gatewaysWithActiveJob = _context.Gateways
        .Where(g => g.Type == GatewayType.Owa4x)
        .Include(g => g.Jobs)
        .Where(_gatewayHasActiveJob)
        .Where(_jobIsNotStarted)
        .ToList();

    foreach (var gateway in gatewaysWithActiveJob)
    {
        _ = Task.Run(() => ExecuteActiveJobAsync(gateway.Id));
        gateway.GetMostRecentJob().JobExectionDate = DateTime.Now;
    }

    _context.Gateways.UpdateRange(gatewaysWithActiveJob);
    await _context.SaveChangesAsync();
}

我们采用Fire and Forget模式触发任务,不等待任务完成就告知数据库任务已启动,原因是部分任务(如向网关上传文件)耗时数分钟,若阻塞会影响用户体验。每个任务线程拥有独立数据库上下文,可更新任务的错误或完成状态:

private async Task ExecuteActiveJobAsync(Guid gatewayId)
{
    // Caution: do not use members other than the scopeFactory as each thread shall have its own scope
    using (var scope = _serviceScopeFactory.CreateScope())
    {
        await using var scopedContext = scope.ServiceProvider.GetRequiredService<SuncarContext>();
        // Below: Task that will be done in this job
    }
}

该方案并非完全“遗忘”任务,仅在系统重启时可能丢失任务,我们会在BackgroundService初始化时重新排队未完成的已启动任务。

近期同事提出不应使用Fire and Forget模式,建议改用Hangfire。我知道Hangfire针对后台任务做了优化,但这种基于后台服务、带数据库连接的无等待线程方案是否可行?是否需要切换到Hangfire?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:07:36