我提到了以下问题,但没有帮我解决问题。在Quartz.net中,一次运行一个作业的一个实例
In Quartz.NET is there a way to set a property that will only allow one instance of a Job to run?
https://github.com/quartznet/quartznet/issues/469
对于CronTrigger,用于调度cs.WithMisfireHandlingInstructionDoNothing()
以下。
将以下属性应用于HelloJob
DisallowConcurrentExecution
。
代码发生了什么?
在Execute方法中,我设置了重点。基于我的代码,execute方法将在10秒内执行。
打到第一个突破点后,我又等了31秒。然后根据我的预期,我已经移除了突破点并执行了代码,应该只执行一次另一次尝试。
但执行方法在另一个 10秒内执行3次(3 * 10秒)。
如何解决这个问题?
调度程序代码。
ISchedulerFactory schedFact = new StdSchedulerFactory();
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("myJob", "group1")
.Build();
// Trigger the job to run now, and then every 40 seconds
ITrigger trigger = trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithCronSchedule("0/10 * * * * ?",cs=>cs.WithMisfireHandlingInstructionDoNothing())
.ForJob("myJob", "group1")
.Build();
TriggerKey key = new TriggerKey("trigger3", "group1");
sched.ScheduleJob(job, trigger);
作业执行代码。
[DisallowConcurrentExecution]
public class HelloJob : IJob
{
public static int count = 1;
public void Execute(IJobExecutionContext context)
{
Console.WriteLine(count+" HelloJob strted On." + DateTime.Now.ToString());
if (count == 1)
Thread.Sleep(TimeSpan.FromSeconds(30));
Interlocked.Increment(ref count);
}
}
====================================== ==============================
解决方案
没有必要去为互锁或手工管理。
石英已经被设计成只有完成第一个时间表,下一个开始。
所以我们不必担心它会同时运行。
例如(像我这样的人:-p),调度程序安排了10分钟。
但是,如果我们在执行方法中复制以下代码,则可以看到, 第一次完成需要20分钟。 第二次完成需要15分钟。
在10分钟之后不会有下一个计划开始。
var startTime = DateTime.UtcNow;
if (count == 1)
{
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(20))
{
// Execute your loop here...
}
}
else if (count > 1)
{
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(15))
{
// Execute your loop here...
}
}
count++;
您是否尝试过在没有附加调试器的情况下执行?只写日志?也许调试器会影响行为。 –
我想运行超过10秒的执行。所以我试着用调试器。 –
无论如何,尝试使用'Thread.Sleep'来代替调试器来确认问题。调试器会影响执行。 –