Hangfire按时间范围获取失败任务的实现及性能疑问
问题解答
过滤执行的层面
你现在的代码是在内存里做过滤。hangfireMonitoringApi.FailedJobs(0, (int)failedCount)会先把所有失败任务从数据库拉到内存中,后面的.Where(...)是LINQ对内存集合的操作,并非在数据库层面执行过滤。如果失败任务量很大,这种方式会拖慢性能,还会占用不必要的内存资源。
按时间范围获取失败任务的推荐方案
最高效的方式是直接通过Hangfire的底层存储连接,在数据库层面完成时间过滤,避免拉取全量数据。代码示例如下:
using Hangfire.Storage; using System.Linq; // 获取Hangfire的存储连接实例 var storageConnection = JobStorage.Current.GetConnection(); // 从"failed"集合中获取任务ID,再筛选符合时间条件的任务数据 var recentFailedJobs = storageConnection.GetAllEntriesFromSet("failed") .Select(jobId => storageConnection.GetJobData(jobId)) .Where(job => job != null && job.FailedAt <= DateTime.UtcNow.AddHours(-1)) .ToList();
如果你的场景对性能要求极高,还可以直接针对Hangfire的数据库表编写查询(以SQL Server为例):
SELECT j.Id, j.InvocationData, j.FailedAt FROM Hangfire.Job j INNER JOIN Hangfire.State s ON j.Id = s.JobId WHERE s.Name = 'Failed' AND j.FailedAt >= DATEADD(HOUR, -1, GETUTCDATE())
用ADO.NET或ORM执行该SQL查询,完全在数据库端完成过滤,性能最优。
要是你更倾向于使用MonitoringApi,也可以分页分批拉取并过滤,但这种方式的效率仍不如直接操作存储或数据库。
内容的提问来源于stack exchange,提问作者net-junkie
相关产品推荐
相关产品推荐

