如何在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
相关产品推荐
相关产品推荐

