2016-04-14 97 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 
} 

希望这有助于...