我正在构建一个Windows服务,该服务正在执行计划的任务,该任务使用Quartz.net以固定的时间间隔(每分钟一次)处理(来自旧系统的)命令队列。

如果任务花费的时间超过1分钟,这是不寻常的,但在某些情况下是可能的,那么我希望它简单地忽略它错过触发的触发器。

但是我似乎无法做到这一点。它执行处理,然后快速连续快速触发所有错过的触发器。据我了解,您可以为失火设置一个阈值,但是我似乎无法使它正常工作。

我在作业上使用[DisallowConcurrentExecution()]以确保在任何一次仅运行作业的一个实例。

以下是几个片段。首先传递一些配置信息-这是您设置失火阈值的方式吗?

    NameValueCollection config = new NameValueCollection();
    config.Add("quartz.jobStore.misfireThreshold", "600000");

    schedFact = new StdSchedulerFactory(config);

使用我认为是正确的忽略失火设置来构建触发器:
    var trigger = TriggerBuilder.Create()
                    .WithIdentity("trigger1", "group1")
                    .StartNow()
                    .WithSimpleSchedule(   x => x.WithMisfireHandlingInstructionIgnoreMisfires()
                    .WithIntervalInSeconds(60)
                    .RepeatForever())
                    .Build();

思想大加赞赏。

工作代码:
此时,您只需要考虑一些粗略的想法,就可以在控制台应用程序中运行该应用程序,并随机延迟一项工作,因此它会在为此设置的10秒间隔内进行拍摄。经过几次延误后,所有备份的失火都迅速相继触发。
[DisallowConcurrentExecution()]
public class SomeJob : IJob
{
    public SomeJob() { }
    public void Execute(IJobExecutionContext context)
    {
        Random rnd = new Random(DateTime.UtcNow.Second);
        int delay = rnd.Next(2);
        Console.WriteLine("Executing Job with delay of "+ delay + "  at " + DateTime.UtcNow.ToString());

        if (delay == 1)
        {
            System.Threading.Thread.Sleep(1000 * 25); // sleep for 25 seconds
        }
    }
}





Example console output:
Executing Job with delay of 1  at 21/05/2015 21:27:17
Executing Job with delay of 1  at 21/05/2015 21:27:42
Executing Job with delay of 0  at 21/05/2015 21:28:07 <-- stacked misfires
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:07 <--
Executing Job with delay of 0  at 21/05/2015 21:28:16
Executing Job with delay of 0  at 21/05/2015 21:28:26
Executing Job with delay of 1  at 21/05/2015 21:28:36
Executing Job with delay of 0  at 21/05/2015 21:29:01
Executing Job with delay of 0  at 21/05/2015 21:29:01
Executing Job with delay of 1  at 21/05/2015 21:29:06

最佳答案

WithMisfireHandlingInstructionIgnoreMisfires()是您所需的错误方法,这并不意味着作业不会触发失火,而是意味着它将尽快触发所有错过的触发器,然后将其恢复为常规时间表。您所看到的正在发生。

您需要的是WithMisfireHandlingInstructionNextWithRemainingCount()。这将通知调度程序忽略失火并等待下一个调度时间。
错误处理的策略可能会有些困惑,有关简洁的说明,请看here(它用于Java调度程序,但这并不重要)。

即使采用正确的策略,您也需要了解失火阈值的工作原理-如果弄错了阈值,则失火的触发器仍可能会触发。

从文档中:“失火是触发器必须错过其下一次触发时间才能将其视为“未触发”并因此应用其失火指令的时间跨度”。

您已将值设置为600000毫秒(并且此值适用于所有触发器,不幸的是每个触发器没有阈值)-失火策略仅在触发器应在触发时间后触发600000毫秒的情况下才会应用。您可以根据需要降低或增加它。

有关失火阈值的更多信息,请阅读here

09-28 00:47