首页 > 解决方案 > 当第一个触发器忙时,石英触发器会堆积

问题描述

我有第二个触发器WithMisfireHandlingInstructionDoNothing

var trigger = TriggerBuilder.Create()
   .WithIdentity("trigger1", "group1")
   .WithCronSchedule("0/1 0/1 0/1 1/1 * ? *", x => x.WithMisfireHandlingInstructionDoNothing())
   .StartNow()
   .Build();

具有以下 JobDetail:

var jobDetail = JobBuilder.Create<TestJob>()
   .WithIdentity(JobKey.Create("TestJob")).Build();

TestJob本身DisallowConcurrentExecution

[DisallowConcurrentExecution] 
public class TestJob : IJob
{
    private static int counter;

    public Task Execute(IJobExecutionContext context)
    {
        var threadId = Thread.CurrentThread.ManagedThreadId;

        Console.WriteLine($"Job start on thread: {threadId}. datetime: {DateTime.Now}");
        if (counter++ < 3)
        {
            Console.WriteLine("Sleeping.");
            Thread.Sleep(5000);
        }

        Console.WriteLine($"Job END on thread: {threadId}. datetime: {DateTime.Now}");

        return Task.CompletedTask;
    }
}

这是调度程序的初始化方式:

var scheduler = new StdSchedulerFactory().GetScheduler().GetAwaiter().GetResult();
scheduler.ScheduleJob(jobDetail, trigger);
scheduler.Start();

我得到的输出是:

Job start on thread: 6. datetime: 14/07/2020 9:45:15
Sleeping.
Job END on thread: 6. datetime: 14/07/2020 9:45:20
Job start on thread: 12. datetime: 14/07/2020 9:45:20
Sleeping.
Job END on thread: 12. datetime: 14/07/2020 9:45:25
Job start on thread: 15. datetime: 14/07/2020 9:45:25
Sleeping.
Job END on thread: 15. datetime: 14/07/2020 9:45:30
Job start on thread: 13. datetime: 14/07/2020 9:45:30
Job END on thread: 13. datetime: 14/07/2020 9:45:30
Job start on thread: 15. datetime: 14/07/2020 9:45:30
Job END on thread: 15. datetime: 14/07/2020 9:45:30
Job start on thread: 12. datetime: 14/07/2020 9:45:30
Job END on thread: 12. datetime: 14/07/2020 9:45:30
Job start on thread: 6. datetime: 14/07/2020 9:45:30
Job END on thread: 6. datetime: 14/07/2020 9:45:30
Job start on thread: 13. datetime: 14/07/2020 9:45:30
Job END on thread: 13. datetime: 14/07/2020 9:45:30
Job start on thread: 14. datetime: 14/07/2020 9:45:30
Job END on thread: 14. datetime: 14/07/2020 9:45:30
Job start on thread: 15. datetime: 14/07/2020 9:45:30
Job END on thread: 15. datetime: 14/07/2020 9:45:30
Job start on thread: 14. datetime: 14/07/2020 9:45:30
Job END on thread: 14. datetime: 14/07/2020 9:45:30
Job start on thread: 15. datetime: 14/07/2020 9:45:30
Job END on thread: 15. datetime: 14/07/2020 9:45:30
Job start on thread: 6. datetime: 14/07/2020 9:45:30
Job END on thread: 6. datetime: 14/07/2020 9:45:30
Job start on thread: 14. datetime: 14/07/2020 9:45:30
Job END on thread: 14. datetime: 14/07/2020 9:45:30
Job start on thread: 13. datetime: 14/07/2020 9:45:30
Job END on thread: 13. datetime: 14/07/2020 9:45:30
Job start on thread: 14. datetime: 14/07/2020 9:45:30
Job END on thread: 14. datetime: 14/07/2020 9:45:30
Job start on thread: 13. datetime: 14/07/2020 9:45:31
Job END on thread: 13. datetime: 14/07/2020 9:45:31
Job start on thread: 6. datetime: 14/07/2020 9:45:32
Job END on thread: 6. datetime: 14/07/2020 9:45:32

如您所见,工作不是并发的,这很好。但我不想要的是第二个作业触发器在前 3 次运行中睡眠时堆积起来。在 3 次运行之后,所有堆叠的触发器都将立即触发。从 开始14/07/2020 9:45:30,该作业至少被调用 15 次。这是我不想要的行为。我不希望这些电话在工作繁忙时堆积起来。

我以为我可以用WithMisfireHandlingInstructionDoNothing这个,但它没有效果。

我希望这很清楚,感谢您的帮助。

编辑

可能misfireThreshold与我得到的有关。如何在 C# 中配置它?

标签: c#quartz-schedulerquartz.net

解决方案


正如您所指出的,问题在于失火阈值。

如果未通过此超时,则不认为触发器未触发,因此您需要减少它。

你可以这样做:

NameValueCollection props = new NameValueCollection
{
    .....,
    { "quartz.jobStore.misfireThreshold", "1000" },
    .....
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);

但这取决于您配置石英实例的方式。

如果您使用配置文件,您可以添加:

quartz.jobStore.misfireThreshold = 1000

推荐阅读