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

如何测量Hangfire作业执行耗时及批量作业完成总时长?

测量Hangfire批量作业总完成时长的方法

这里提供几种实用方案,适合你测试20-40个Hangfire作业的整体完成耗时:

方案一:自定义作业过滤器追踪全局时间

通过Hangfire的过滤器机制,统一追踪这批作业的开始与结束时间,核心是用线程安全的计数器判断所有作业是否完成:

  1. 创建自定义过滤器类:
public class BatchJobTrackingFilter : JobFilterAttribute, IElectStateFilter
{
    private static int _totalJobs;
    private static DateTime _batchStartTime;
    private static int _completedJobs;
    private static DateTime _batchEndTime;

    // 初始化批量作业的总数量和开始时间
    public static void InitializeBatch(int jobCount)
    {
        Interlocked.Exchange(ref _totalJobs, jobCount);
        Interlocked.Exchange(ref _completedJobs, 0);
        _batchStartTime = DateTime.UtcNow;
        _batchEndTime = DateTime.MinValue;
    }

    public void OnStateElection(ElectStateContext context)
    {
        // 仅处理成功完成的作业
        if (context.CandidateState is SucceededState)
        {
            var completed = Interlocked.Increment(ref _completedJobs);
            // 当最后一个作业完成时记录结束时间
            if (completed == _totalJobs)
            {
                _batchEndTime = DateTime.UtcNow;
                var totalDuration = _batchEndTime - _batchStartTime;
                // 这里可将时长输出到日志、控制台或存储
                Console.WriteLine($"所有作业完成,总耗时:{totalDuration.TotalSeconds:F2}秒");
            }
        }
    }
}
  1. 使用方式:
    • 启动Hangfire时注册全局过滤器:GlobalJobFilters.Filters.Add(new BatchJobTrackingFilter());
    • 创建作业前调用初始化方法:BatchJobTrackingFilter.InitializeBatch(30);(假设创建30个作业)
    • 正常创建所有Hangfire作业,过滤器会自动追踪完成状态

方案二:批量标记+定时查询存储

给这批作业添加统一标识,通过查询Hangfire存储判断完成状态,适合不需要全局过滤器的场景:

  1. 创建作业时添加自定义参数:
var batchId = Guid.NewGuid().ToString();
var totalJobs = 30;
var batchStartTime = DateTime.UtcNow;

// 创建30个作业,每个携带batchId参数
for (int i = 0; i < totalJobs; i++)
{
    BackgroundJob.Enqueue(() => YourJobMethod(i)).SetJobParameter("BatchId", batchId);
}
  1. 定时查询完成情况:
    可以用单独的后台任务或控制台程序定期检查:
var connection = JobStorage.Current.GetConnection();
bool allCompleted = false;

while (!allCompleted)
{
    // 查询该批次下成功的作业数量
    var succeededJobs = connection.GetJobsByStateName("Succeeded")
        .Where(job => job.GetJobParameter<string>("BatchId") == batchId)
        .Count();

    if (succeededJobs == totalJobs)
    {
        var totalDuration = DateTime.UtcNow - batchStartTime;
        Console.WriteLine($"所有作业完成,总耗时:{totalDuration.TotalSeconds:F2}秒");
        allCompleted = true;
    }
    else
    {
        // 每隔1秒查询一次,可根据实际调整间隔
        Thread.Sleep(1000);
    }
}

方案三:利用Hangfire.Batches扩展(若已使用)

如果项目引入了Hangfire.Batches包,可直接利用批量作业的完成事件:

var batchStartTime = DateTime.UtcNow;

// 创建批量作业
var batchId = BatchJob.StartNew(batch =>
{
    for (int i = 0; i < 30; i++)
    {
        batch.Enqueue(() => YourJobMethod(i));
    }
});

// 监听批量完成事件
BatchJob.OnBatchSucceeded(batchId, () =>
{
    var totalDuration = DateTime.UtcNow - batchStartTime;
    Console.WriteLine($"批量作业完成,总耗时:{totalDuration.TotalSeconds:F2}秒");
});

注意:若用SQL Server作为Hangfire存储,也可直接通过SQL语句统计特定批次的成功作业数,效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:52:17