在Hangfire中应使用内部API还是EF Db Context操作作业数据?
Hangfire 筛选失败作业并重新入队实现方案
完全可以通过Hangfire公开API实现该需求,无需直接调用内部API或操作EF Context读写Hangfire库表,官方提供的公开接口已经覆盖了相关能力,且能避免直接操作数据库导致的作业状态异常问题。
具体实现步骤
- 前置依赖:确保项目已引用
Hangfire.CoreNuGet包 - 第一步:拉取所有失败状态的作业
using Hangfire; using Hangfire.States; using Hangfire.Storage; // 获取Hangfire存储连接 using var connection = JobStorage.Current.GetConnection(); // 拉取全量失败作业,可根据业务规模调整分页参数 var allFailedJobs = connection.GetJobsByState(StateNames.Failed, from: 0, count: int.MaxValue);
- 第二步:匹配指定的目标执行方法
可通过作业实例的Job属性获取对应方法的类型、方法名、入参信息,按需做匹配规则即可,示例匹配OrderService类下的SyncInventory方法:
// 定义目标方法的匹配规则 var targetDeclaringType = typeof(OrderService); var targetMethodName = nameof(OrderService.SyncInventory); // 筛选匹配的失败作业 var matchedJobs = allFailedJobs.Where(jobItem => jobItem.Job.Type == targetDeclaringType && jobItem.Job.Method.Name == targetMethodName).ToList(); // 如需更精准匹配,可追加判断jobItem.Job.Args的入参值
- 第三步:将匹配作业重新入队
var jobClient = new BackgroundJobClient(); foreach (var job in matchedJobs) { // 调用Requeue方法即可自动将作业从失败状态改为待执行状态,返回值为操作是否成功 bool requeueResult = jobClient.Requeue(job.Key); }
注意事项
- 若你的业务场景是调整配置后重跑作业,原作业的入参如果关联旧配置,建议不要直接调用Requeue,可读取原作业的入参后结合新配置调用
BackgroundJob.Enqueue生成新作业入队 - Hangfire默认会自动清理超过保留时长的历史作业,若失败作业已被清理则无法查询到
- 全量拉取失败作业时如果作业量极大,建议分页拉取,避免内存占用过高
内容的提问来源于stack exchange,提问作者Gillardo
相关产品推荐
相关产品推荐

