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

如何在Hangfire后台作业失败耗尽重试次数后执行指定操作

实现Hangfire特定作业耗尽重试后的邮件通知

针对你的需求,只需要监听PerformActionA作业的最终失败状态(耗尽重试次数),可以通过Hangfire的**作业过滤器(Job Filter)**来实现,以下是具体步骤:

1. 自定义失败状态监听过滤器

Hangfire提供了IApplyStateFilter接口,用于监听作业状态的变更。我们可以实现这个接口,只处理进入Failed状态的作业,并判断是否是目标方法且重试次数耗尽。

代码示例(全局过滤+方法判断)

public class FailedActionANotificationFilter : IApplyStateFilter
{
    public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
    {
        // 仅处理作业进入Failed状态的情况
        if (context.NewState is not FailedState) return;

        // 定位目标作业方法:PerformActionA
        var jobMethod = context.Job.Method;
        var isTargetJob = jobMethod.Name == nameof(YourClass.PerformActionA)
                          && jobMethod.DeclaringType == typeof(YourClass)
                          // 如果有重载,可加上参数类型判断避免误匹配
                          && jobMethod.GetParameters().Length == 2
                          && jobMethod.GetParameters()[0].ParameterType == typeof(Param1Type)
                          && jobMethod.GetParameters()[1].ParameterType == typeof(Param2Type);

        if (!isTargetJob) return;

        // 检查是否耗尽重试次数:当前重试次数 >= 最大允许次数-1(因为首次执行不算重试)
        var retryCount = context.Job.RetryCount;
        var maxAttempts = context.Job.MaxAttempts;
        if (retryCount >= maxAttempts - 1)
        {
            // 异步触发邮件通知(用Hangfire队列执行,避免阻塞状态变更流程)
            BackgroundJob.Enqueue(() => NotifyUser.NotifyAboutFailedPerformActionAsync());
        }
    }

    public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
    {
        // 无需处理状态移除逻辑
    }
}

可选:改为特性式过滤(仅给目标方法绑定)

如果不想全局注册过滤器,也可以把过滤器改成特性,直接标记在PerformActionA方法上:

public class NotifyOnActionAFailureAttribute : JobFilterAttribute, IApplyStateFilter
{
    public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
    {
        if (context.NewState is not FailedState) return;

        var retryCount = context.Job.RetryCount;
        var maxAttempts = context.Job.MaxAttempts;
        if (retryCount >= maxAttempts - 1)
        {
            BackgroundJob.Enqueue(() => NotifyUser.NotifyAboutFailedPerformActionAsync());
        }
    }

    public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction) { }
}

// 给目标方法添加特性
[NotifyOnActionAFailure]
// 可自定义重试次数,默认是10次(1次执行+9次重试)
[AutomaticRetry(Attempts = 3)]
public void PerformActionA(Param1Type param1, Param2Type param2)
{
    // 你的业务逻辑
}

2. 注册过滤器(全局方式需要这一步)

在Hangfire的启动配置中,把自定义过滤器添加到全局作业过滤器集合:

// 在Startup.cs或Program.cs中配置Hangfire
services.AddHangfire(config =>
{
    config.UseSqlServerStorage("YourHangfireConnectionString");
    // 添加全局过滤器
    config.GlobalJobFilters.Add(new FailedActionANotificationFilter());
});

services.AddHangfireServer();

关键注意事项

  • 重试次数判断:Hangfire的RetryCount是已执行的重试次数,MaxAttempts是总允许的执行次数(首次执行+重试次数)。比如设置[AutomaticRetry(Attempts = 3)],则MaxAttempts=3,当RetryCount=2时,就是最后一次重试失败,需要触发通知。
  • 异步通知处理:不要在过滤器中直接await异步方法(因为OnStateApplied是同步方法),通过BackgroundJob.Enqueue把通知任务加入Hangfire队列,保证异步执行且不阻塞状态变更。
  • 方法匹配严谨性:如果PerformActionA有重载,一定要加上参数类型判断,避免误触发其他重载方法的通知。

内容的提问来源于stack exchange,提问作者Prabhath Kumar Rayabarapu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:18:16