2012-11-07 54 views
4

這是我的石英配置:如何忽略Quartz.Net中的失火?

<quartz> 
    <add key="quartz.scheduler.instanceName" value="EmailScheduler" /> 
    <!-- Configure Thread Pool --> 
    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" /> 
    <add key="quartz.threadPool.threadCount" value="10" /> 
    <add key="quartz.threadPool.threadPriority" value="Normal" /> 
    <!-- Configure Job Store --> 
    <add key="quartz.jobStore.misfireThreshold" value="60000" /> 
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" /> 
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz" /> 
    <add key="quartz.jobStore.dataSource" value="default" /> 
    <add key="quartz.jobStore.lockHandler.type" value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz" /> 
    <add key="quartz.dataSource.default.provider" value="SqlServer-20" /> 
    <add key="quartz.dataSource.default.connectionString" value="data source= ......" /> 
    <add key="quartz.jobStore.tablePrefix" value="QRTZ_" /> 
    </quartz> 

這裏是我IInterruptableJob

public class JobC : Quartz.IInterruptableJob 
{ 
    public void Interrupt() 
    { 
     Console.WriteLine("Job Interrupt() called at " + DateTime.Now); 
    } 

    public void Execute(IJobExecutionContext context) 
    { 
     // what code i should write here to detect misfires??? 
     Console.WriteLine("FireTime at " + context.FireTimeUtc.Value + " PreviousFireTime at:" + (context.PreviousFireTimeUtc.HasValue ? context.PreviousFireTimeUtc.Value.ToString() : "NULL")); 
    } 
} 

這是我的工作,並觸發:

var job = JobBuilder.Create<JobC>().WithIdentity(new JobKey("JobC")).RequestRecovery(true).Build(); 
var trigger = TriggerBuilder.Create() 
    .WithSimpleSchedule(x => x 
     .RepeatForever() 
     .WithIntervalInSeconds(2) 
      // I'm ignoring misfires here, but seems it not works! 
     .WithMisfireHandlingInstructionIgnoreMisfires()) 
    .StartNow() 
    .Build(); 

var scheduler = new Quartz.Impl.StdSchedulerFactory().GetScheduler(); 
scheduler.Start(); 
scheduler.ScheduleJob(job, trigger); 

後,我打電話scheduler.PauseAll()所有作業暫停後呼籲scheduler.ResumeAll()全部錯過了火災,起火!但我想忽略它們,現在就繼續。

在此先感謝。

回答

2

它可能看起來愚蠢,但我做了以下擴展的方法來檢測裏面Execute方法擦槍走火:

public static bool IsMissedFire(this IJobExecutionContext context, int offsetMilliseconds) 
{ 
    if (!context.ScheduledFireTimeUtc.HasValue) 
     return false; 
    if (!context.FireTimeUtc.HasValue) 
     return false; 

    var scheduledFireTimeUtc = context.ScheduledFireTimeUtc.Value; 
    var fireTimeUtc = context.FireTimeUtc.Value; 

    return fireTimeUtc.Subtract(scheduledFireTimeUtc).TotalMilliseconds > offsetMilliseconds; 
} 

用法很簡單:

public void Execute(IJobExecutionContext context) 
{ 
    if (context.IsMissedFire(1000)) 
     Console.WriteLine("Missfire"); 
    else 
     Console.WriteLine("Fire"); 
} 
3

你確定你的觸發器符合定義的失火閾值嗎?如果您在配置狀態時擁有60秒的閾值,則每個不被視爲失火但已達到其預定火災時間的觸發將在恢復後儘快觸發。

因此,如果您的暫停持續至少閾值(在此情況下爲60秒),您應該看到忽略行爲。

+0

是否可以指定每個觸發器的閾值?因爲一些觸發器具有不同的間隔,所以一個閾值對所有觸發器都不方便。 – Jalal

+0

不幸的是,閾值是作業存儲級別配置。 –

+0

現在我已將失火閾值配置更改爲''但仍然存在相同的問題。我一定誤解了WithMisfireHandlingInstructionIgnoreMisfires功能。 'IJobExecutionContext'中是否有解決方案來檢測'Execute'函數中的失火? – Jalal

3

雖然它是石英的Java版本中,下面的鏈接給出了不同的失火策略的很好的概述:

http://nurkiewicz.blogspot.co.uk/2012/04/quartz-scheduler-misfire-instructions.html

本質上,一旦線程變得可用,使用MisfireHandlingInstructionIgnoreMisfires實際上會執行失火,這看起來非常不直觀。爲了放棄所有失火併繼續進行計劃,您需要使用MisfireHandlingInstructionNextWithRemainingCount。