我提到了以下問題,但沒有幫我解決問題。在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'來代替調試器來確認問題。調試器會影響執行。 –