Quartz.NET – 在Job完成完全执行后调用一个函数
我们使用Quartz.Net在Windows服务中按计划触发作业。 我有一种情况,我必须每5 minutes
从Start DateTime
到End DateTime
触发一个工作。
作业完成后,我们需要计算Next Start DateTime
和Next End DateTime
并保存到DB –
为此,我试图覆盖JobListener
,它有一个方法: JobWasExecuted
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); } }
以及TriggerComplete
中的TriggerListener
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
,每隔5秒结束12:02 AM
– 这两种方法都会被调用12 times
我需要的是在One Job迭代结束后只调用一次方法 – (作业执行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表达式可以看出,它将在每周Tuesday
和Wednesday
每隔5 minutes
从7 AM to 7:45 AM
运行。
所以1次迭代是Tuesday
7AM to 7:45 AM
,下一个是Wednesday
7 AM to 7:45
。 我需要在每次迭代完成后调用一个函数。
所以,假设当7:45 AM on Tuesday
触发Last Trigger时,我需要调用该函数。
如果我正确理解您的问题,您可以使用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); } }
通过使用StartTime
或EndTime
作为全局值,创建在给定时间段内每分钟触发一次的另一个作业怎么办?
除此之外,您还可以在调用action方法之前检查EndTime
值。 在这种情况下,如果当前时间等于或接近DateTime.Now()
或类似的内容,则执行操作:
//... if(endtime == DateTime.Now()) { //call your action }
希望这可以帮助…