[英]Quartz.net Run 1 instance of a job with different JobKey and JobData
[英]In Quartz.net, run one instance of a job at a time
我已經提到了以下問題,但沒有幫助我解決問題。
在 Quartz.NET 中,有沒有一種方法可以設置一個只允許一個 Job 實例運行的屬性?
https://github.com/quartznet/quartznet/issues/469
對於 CronTrigger,在調度程序cs.WithMisfireHandlingInstructionDoNothing()
使用了以下內容。
在HelloJob
應用以下屬性
DisallowConcurrentExecution
。
代碼怎么了?
在 Execute 方法中,我已經設置了斷點。 根據我的代碼,execute 方法將在每個 10 秒內執行。
打到第一個斷點后,又等了31秒。 然后我刪除了斷點並執行了代碼,根據我的期望,應該只執行一次以進行另一次嘗試。
但是 execute 方法在另外 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);
}
}
================================================== ==================
無需進行互鎖或手動管理。
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++;
在您的情況下發生的情況是,在作業Quartz
第一個長 30 秒執行期間安排了其他三個執行。 這就是為什么在長時間執行之后看到三個短執行。 它們不是同時執行的。 一個接一個,但沒有延遲。 Quartz
就是這樣設計的。
[DisallowConcurrentExecution]
public class HelloJob : IJob
{
public static int count = 1;
public void Execute(IJobExecutionContext context)
{
Console.WriteLine("HelloJob strted On." + DateTime.UtcNow.Ticks);
if (count == 1)
Thread.Sleep(TimeSpan.FromSeconds(30));
Interlocked.Increment(ref count);
}
}
和輸出:
Ctrl+C to exit.
HelloJob strted On.636280218500144776
HelloJob strted On.636280218800201691
HelloJob strted On.636280218800211705
HelloJob strted On.636280218800222083
HelloJob strted On.636280218900009629
HelloJob strted On.636280219000000490
看,時間戳是不同的,next 在 first 完成后開始。
如果您想避免這種行為,您應該增加作業之間的延遲,或者按照@BrunoFerreira 的建議手動處理此作業的時間表。
幾天前我遇到了同樣的問題。 結果我不得不取消工作安排,這是觸發器。 當我的應用程序結束時,我正在使用此方法來執行此操作。
private void StopAllJobs()
{
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler, start the schedular before triggers or anything else
sched = schedFact.GetScheduler();
var executingJobs = sched.GetCurrentlyExecutingJobs();
foreach (var job in executingJobs)
{
sched.Interrupt(job.JobDetail.Key);
sched.UnscheduleJob(job.Trigger.Key);
sched.DeleteJob(job.JobDetail.Key);
}
sched.Clear();
}
希望這對你有幫助。
只需使用這樣的東西:
private static readonly SemaphoreSlim Lock = new SemaphoreSlim(1, 1);
if (await Lock.WaitAsync(new TimeSpan(0, 0, 30)))
{
...
}
我們有一些工作,這很好用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.