作业1 计划每5分钟运行一次,大约需要1分钟才能完成。
很多工作堆积如山,工作1 需要15分钟才能运行。
现在有三个作业1 同时处理 - 我不希望这样。
<小时/> 如果已将作业1 再次添加到队列中,该怎么办?
是否有Hangfire设置,或者我是否需要手动轮询作业状态?
答案 0 :(得分:4)
听起来这可能是您可能感兴趣的内容: https://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607/8
讨论是关于跳过将同时执行到已经运行的作业的作业。
答案 1 :(得分:4)
有点晚,但是我正在使用此类来防止重复的作业同时运行
public class SkipConcurrentExecutionAttribute : JobFilterAttribute, IServerFilter, IElectStateFilter
{
private readonly int _timeoutSeconds;
private const string DistributedLock = "DistributedLock";
public SkipConcurrentExecutionAttribute(int timeOutSeconds)
{
if (timeOutSeconds < 0) throw new ArgumentException("Timeout argument value should be greater that zero.");
this._timeoutSeconds = timeOutSeconds;
}
public void OnPerformed(PerformedContext filterContext)
{
if (!filterContext.Items.ContainsKey(DistributedLock))
throw new InvalidOperationException("Can not release a distributed lock: it was not acquired.");
var distributedLock = (IDisposable)filterContext.Items[DistributedLock];
distributedLock?.Dispose();
}
public void OnPerforming(PerformingContext filterContext)
{
filterContext.WriteLine("Job Started");
var resource = String.Format(
"{0}.{1}",
filterContext.BackgroundJob.Job.Type.FullName,
filterContext.BackgroundJob.Job.Method.Name);
var timeOut = TimeSpan.FromSeconds(_timeoutSeconds);
filterContext.WriteLine($"Waiting for running jobs to complete. (timeout: { _timeoutSeconds })");
try
{
var distributedLock = filterContext.Connection.AcquireDistributedLock(resource, timeOut);
filterContext.Items[DistributedLock] = distributedLock;
}
catch (Exception ex)
{
filterContext.WriteLine(ex);
filterContext.WriteLine("Another job is already running, aborted.");
filterContext.Canceled = true;
}
}
public void OnStateElection(ElectStateContext context)
{
//if (context.CandidateState as FailedState != null)
//{
//}
}
}
希望有帮助,谢谢!
答案 2 :(得分:2)
有一个名为DisableConcurrentExecution的属性,可以防止同时运行同一类型的2个作业。
尽管如此,在您的情况下最好是检查任务是否运行并相应地跳过。
答案 3 :(得分:2)
您可以使用DisableConcurrentExecution属性来防止同时多次执行某个方法。只需将此属性放在方法上方 -
即可[DisableConcurrentExecution(timeoutInSeconds: 10 * 60)]
public void Job1()
{
// Metohd body
}
答案 4 :(得分:0)
没有时间阅读关于这个简单概念是否甚至退出框架的github讨论页面上的页面?
如果您想放弃尝试运行两次,如果它已经运行,您可以随时执行此操作(请注意,不会应用任何属性):
private static bool _isRunningUpdateOrders;
public void UpdateOrders()
{
try
{
if (_isRunningUpdateOrders)
{
return;
}
_isRunningUpdateOrders = true;
// Logic...
}
finally
{
_isRunningCreateGen2Data = false;
}
}
答案 5 :(得分:0)
是的,可能如下:
RecurringJob.AddOrUpdate(Environment.MachineName, () => MyJob(Environment.MachineName), Cron.HourInterval(2));
和MyJob应该这样定义:
public void MyJob(string taskId)
{
if (!taskId.Equals(Environment.MachineName))
{
return;
}
//Do whatever you job should do.
}