我们正在使用Quartz.Net在Windows服务中按计划触发作业
。
我有一种情况,我必须从5 minutes
到Start DateTime
每隔End DateTime
触发一份工作。
作业完成后,我们需要计算Next Start DateTime
和Next End DateTime
并保存到数据库 -
为此,我尝试覆盖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表达式可以看出,每7 AM to 7:45 AM
5 minutes
和Tuesday
每隔Wednesday
就会运行7AM to 7:45 AM
。
因此Tuesday
上的1次迭代为7 AM to 7:45
,Wednesday
上的下一次为7:45 AM on Tuesday
。我需要在每次迭代完成后调用一个函数。
所以让我们说当test.py
触发最后一次触发时 - 我需要调用该函数。
答案 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);
}
}
答案 1 :(得分:0)
使用StartTime
或EndTime
作为全局值,创建在给定时间段内每分钟触发一次的另一个作业怎么样?
除此之外,您还可以在调用操作方法之前检查EndTime
值。在这种情况下,如果当前时间等于或接近DateTime.Now()
或类似的内容,则执行操作:
//...
if(endtime == DateTime.Now())
{
//call your action
}
希望这会有所帮助......