【发布时间】:2017-04-17 08:56:12
【问题描述】:
我已经提到了以下问题,但没有帮助我解决问题。
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 秒。然后我删除了断点并执行了代码,根据我的预期,应该只执行一次以进行另一次尝试。
但是execute方法在另一个内执行了3次(3*10秒) 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);
}
}
================================================ ======================
解决方案
无需进行联锁或手动管理。
Quartz 已经设计为只完成第一个时间表,下一个开始。
所以我们不用担心它会同时运行。
例如(像我这样的人 :-p),调度器安排了 10 分钟。
但是如果我们在execute方法中复制下面的代码,你可以看到, 第一次完成需要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而不是调试器来确认问题。调试器会影响执行。 -
我试过threed.sleep但没有帮助。
标签: c# quartz.net