我有一个使用Hangfire进行后台任务和作业的Web应用程序。
我有一个重复的作业,其中不能同时执行2个此类作业实例。假设该作业需要更长时间才能执行。
我想要检查作业当前是否正在运行,如果是,则不再重新运行。
我已经四处寻找信息,但没有找到任何相关内容。
我有一个重复的作业,其中不能同时执行2个此类作业实例。假设该作业需要更长时间才能执行。
我想要检查作业当前是否正在运行,如果是,则不再重新运行。
我已经四处寻找信息,但没有找到任何相关内容。
有很多地方已经回答了部分问题,但是为了让我完全实现这个功能,我必须要做 两件事:
因此,如果您正在使用接口(例如使用依赖注入)启动Hangfire作业,请将它们放在接口定义上。
[DisableConcurrentExecution(10)]
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
如果您没有以这种方式使用AutomaticRetry属性,则默认情况下作业将被添加到计划作业列表中,等待第一个作业完成时运行。
这样可以按照我想要的方式正常工作:
每5分钟运行一次作业。如果在接下来的5分钟时间间隔内,前一个作业仍在运行,则不会排队新实例。
如果您将它们放在实现接口的方法上,则无效。
此答案适用于 Hangfire.Core 1.7.30.0
它具有以下接口
// Assembly Hangfire.Core, Version=1.7.30.0, Culture=neutral, PublicKeyToken=null
namespace Hangfire.Storage
{
public interface IMonitoringApi
{
...
JobList<EnqueuedJobDto> EnqueuedJobs(string queue, int from, int perPage);
JobList<FetchedJobDto> FetchedJobs(string queue, int from, int perPage);
JobList<ProcessingJobDto> ProcessingJobs(int from, int count);
JobList<ScheduledJobDto> ScheduledJobs(int from, int count);
JobList<SucceededJobDto> SucceededJobs(int from, int count);
JobList<FailedJobDto> FailedJobs(int from, int count);
JobList<DeletedJobDto> DeletedJobs(int from, int count);
...
}
}
使用方法如下:
private readonly IMonitoringApi _api;
public object_constructor(Hangfire.JobStorage jobStorage)
{
_api = jobStorage.GetMonitoringApi();
}
public List<dynamic> GetProcessingJobs(int? from = null, int? count = null)
{
var list = _api.ProcessingJobs(from ?? 0, count ?? int.MaxValue);
if (list == null) return new List<dynamic>();
var items = list.Where(kv => kv.Value.Job != null)
.Select(kv => new {
kv.Key,
kv.Value.Job.Method.Name,
kv.Value.InProcessingState,
kv.Value.ServerId,
StartedAt = kv.Value.StartedAt, // UTC
Duration = DateTime.UtcNow - kv.Value.StartedAt,
Args = string.Join(",", kv.Value.Job?.Args.Select(e => e ?? "null"))
})
.OrderByDescending(e => e.StartedAt)
.Cast<dynamic>()
.ToList();
return items;
}
有没有人想过更简单的解决方案?比如一个 SQL 表,其中包含一个位字段来指示“正在处理”。作业将在最开始检查此字段。如果为真,则退出。完成后,将其设置为假。 你有什么想法吗?