2016-04-14 98 views
3

我們使用Quartz.Net在Windows服務 中按計劃觸發作業。 我有一種情況,我必須每5 minutesStart DateTime觸發一個工作,直到End DateTimeQuartz.NET - 作業完成後調用函數完全執行

後作業完成,我們需要計算Next Start DateTimeNext End DateTime並保存到數據庫 -

爲此,我試圖重寫具有方法JobListenerJobWasExecuted

public class xPTJobListener : JobListenerSupport 
{ 
    public override string Name { get { return "xPTJobListener"; } } 

    public override void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) 
    { 

     var dataMap = context.MergedJobDataMap; 
     var schedule = (MyDTO)dataMap["Schedule"]; 

     using (var logger = new xPTLogger()) 
     { 
      logger.LogMessage(MessageType.Information, string.Format("Inside JobWasExecuted() - [{0}] - ", schedule.Id)); 
     } 

     base.JobWasExecuted(context, jobException); 
    } 
} 

,也TriggerCompleteTriggerListener

public class xPTTriggerListener : TriggerListenerSupport 
{ 
    public override string Name { get { return "xPTTriggerListener"; } } 

    public override void TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode) 
    { 

     var dataMap = context.MergedJobDataMap; 
     var schedule = (MyDTO)dataMap["Schedule"]; 

     using (var logger = new xPTLogger()) 
     { 
      logger.LogMessage(MessageType.Information, string.Format("Inside Trigger Complete - [{0}] - ", schedule.Id)); 
     } 


     base.TriggerComplete(trigger, context, triggerInstructionCode); 

    } 
} 

但上述方法的問題在於,每次調用作業時都會執行它們。

所以,如果我有一個從12:01 AM運行結束12:02 AM每5秒一個工作 - 這兩種方法被調用12 times

我需要做的是調用一個方法只有一次1個作業迭代結束後 - (作業執行12次後)?

如何在Quartz中執行此操作?

編輯

創建觸發器

public static ITrigger GenerateTrigger(RouteMonitorScheduleDTO routeSchedule, double fGmtOffset, xPTLogger logger) 
{ 
    ITrigger trigger = null; 

    switch (routeSchedule.ScheduleInfo.PeriodType) 
    { 
     case PeriodTypeEnum.Once: 
      trigger = TriggerBuilder.Create() 
         .WithIdentity(string.Format("trigger_{0}", routeSchedule.RouteScheduleId), DefaultGroup) 
         .StartAt(routeSchedule.DepartureDateTime) 
         .WithSimpleSchedule(s => s.WithIntervalInMinutes(5)) 
         .EndAt(routeSchedule.ArrivalDateTime.AddMinutes(5)) 
         .Build(); 
      break; 
     case PeriodTypeEnum.Daily: 
     case PeriodTypeEnum.WeekDays: 
     case PeriodTypeEnum.Weekly: 
     case PeriodTypeEnum.Monthly: 
      var schedule = routeSchedule.ScheduleInfo;   
      var cronExpresion = xPTCronBuilder.GenerateCronExpression(
            schedule.PeriodType,       
            schedule.ScheduleStringValue, 
            fGmtOffset,    
            routeSchedule.DepartureDateTime, 
            routeSchedule.ArrivalDateTime.AddMinutes(5), 5); 
      trigger = TriggerBuilder.Create() 
         .WithIdentity(string.Format("trigger_{0}", routeSchedule.RouteScheduleId), DefaultGroup) 
         .WithCronSchedule(cronExpresion) 
         .Build(); 
      break; 
    } 

    return trigger; 
} 

編輯 觸發使用Cron:

trigger = TriggerBuilder.Create() 
.WithIdentity(string.Format("trigger_{0}", 1), "Group1") 
.WithCronSchedule("0 0-45/5 7-7 ? * TUE,WED *").Build(); 

你可以從cron表達式上面看到它將從每運行5 minutesTuesdayWednesday

所以1次迭代是7AM to 7:45 AM on Tuesday,接下來是7 AM to 7:45 on Wednesday。我需要在每次迭代完成後調用一個函數。

所以我們假設當最後的觸發器被觸發爲7:45 AM on Tuesday - 我需要調用該函數。

+0

你是什麼意思是「整個作業」嗎?你正在執行這個工作12次,所以你爲什麼期望這些方法只被調用一次? – yonisha

+0

這就是我需要的 - 經過一次完整的迭代後,我需要啓動一個方法來計算下一個開始和結束日期 –

+0

也許你的工作課上有一個靜態計數器? –

回答

2

如果我正確理解你的問題,你可以通過以下方式使用ITriggerListener做到這一點:

public class xPTTriggerListener : TriggerListenerSupport { 
    public override string Name 
    { 
     get { return "xPTTriggerListener"; } 
    } 

    public override void TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode) { 
     if (triggerInstructionCode == SchedulerInstruction.DeleteTrigger) { 
      // means this trigger won't be fired again - now recalculate your dates in database 
     } 
     base.TriggerComplete(trigger, context, triggerInstructionCode); 
    } 
} 
+0

正如在上面的問題中提到的,我已經試過了。但這不是我所需要的。我需要在完成一次迭代後調用函數 –

+0

@DawoodAwan註釋條件triggerInstructionCode == SchedulerInstruction.DeleteTrigger。在最後一次迭代之後,這將只執行一次。 – Evk

+0

@DawoodAwan我實際上有機會今天驗證它,它確實按預期工作:整個TriggerComplete將運行多次(比如說12次),但指令將只是SchedulerInstruction.DeleteTrigger一次 - 在最後一次迭代中,當觸發器不會觸發任何更多。 – Evk

0

什麼有關創建另一份工作在這一段時間一分鐘使用StartTimeEndTime作爲觸發一次全球價值?

除此之外,您還可以在調用您的操作方法之前檢查EndTime的值。在這種情況下,你如果當前時間等於或接近DateTime.Now()或類似的東西執行的操作:

//... 
if(endtime == DateTime.Now()) 
{ 
    //call your action 
} 

希望這有助於...