【问题标题】:Prevent Triggers Being Fired Simultaneously防止同时触发触发器
【发布时间】:2015-01-15 23:54:36
【问题描述】:

有没有办法告诉 Quartz.NET 不要同时触发两个触发器?这意味着如果触发器A 和触发器B 具有完全相同的时间表,那么触发器B 会等待一定的时间然后触发?

我在我的程序中看到,当我的两个作业都从同一个文件中读取并执行同一个.exe 文件时,这可能会导致问题。这会导致我尚未弄清楚的未捕获异常。

我不确定 Quartz.NET 是如何处理这个问题的。但是有没有办法延迟这种触发(即使只是几秒钟)?

【问题讨论】:

  • Quartz.NET 管理并发不是在调度程序级别,而是使用可以添加到 Job 类的属性。 [DisallowConcurrentExecutionAttribute] 避免同时执行给定作业的多个实例。或者,在每个作业中,您可以使用MutexReaderWriterLock 同步对共享资源的访问。

标签: c# quartz.net job-scheduling


【解决方案1】:

您可以在工作中使用DisallowConcurrentExecutionAttribute

[DisallowConcurrentExecutionAttribute]
class DisallowConcurrentJob : IJob
{
   //Implementation goes here
}

它可以防止一个作业的多个实例 WITH THE SAME KEY 运行 同时。

一个很好的解释可以找到here

更新:

如果您想确保触发器/作业始终运行,您可以使用misfire 说明:

IJobDetail job1 = JobBuilder.Create<InheritedJob1>()
    .WithIdentity("DisallowConcurrentJob", "MYGROUP")
    .RequestRecovery(true)
    .Build();

//Schedule this job to execute every second, a maximum of 5 times
ITrigger trigger1 = TriggerBuilder.Create()
    .WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForTotalCount(5)
        .WithMisfireHandlingInstructionFireNow())
    .StartNow()
    .WithIdentity("DisallowConcurrentJobTrigger", "MYGROUP")
    .Build();

Scheduler.ScheduleJob(job1, trigger1);

WithMisfireHandlingInstructionFireNow

The job is executed immediately after the scheduler discovers misfire situation.

【讨论】:

  • 但是这些不是具有相同密钥的工作。
  • 当您使用 DisallowConcurrentExecutionAttribute 时,这是否意味着其他作业将等待或根本不运行?
  • 感谢您的回答。问题确实不失火。因为我可以看到程序已经运行了。但是由于一些未捕获的错误被终止。所以我需要的不是失火策略,而是一种让同步作业稍微延迟运行的方法。
  • 我的建议是避免 2 个作业(相同的键)同时运行,但延迟那些有冲突的作业。基本上所有的工作都会运行——在某个时候——你不会错过任何一个触发器。