Quartz.NET - 在Job完成完全执行后调用一个函数

时间:2016-04-14 11:00:40

标签: c# quartz-scheduler quartz.net

我们正在使用Quartz.Net在Windows服务中按计划触发作业 。 我有一种情况,我必须从5 minutesStart DateTime每隔End DateTime触发一份工作。

作业完成后,我们需要计算Next Start DateTimeNext 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 minutesTuesday每隔Wednesday就会运行7AM to 7:45 AM

因此Tuesday上的1次迭代为7 AM to 7:45Wednesday上的下一次为7:45 AM on Tuesday。我需要在每次迭代完成后调用一个函数。

所以让我们说当test.py触发最后一次触发时 - 我需要调用该函数。

2 个答案:

答案 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)

使用StartTimeEndTime作为全局值,创建在给定时间段内每分钟触发一次的另一个作业怎么样?

除此之外,您还可以在调用操作方法之前检查EndTime值。在这种情况下,如果当前时间等于或接近DateTime.Now()或类似的内容,则执行操作:

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

希望这会有所帮助......