Quartz.NET - Call a function after the Job has completed Full Execution

有些话、适合烂在心里 提交于 2019-12-12 13:17:14

问题


We are using Quartz.Net to trigger jobs on a schedule in a Windows Service . I have a situation where I have to Trigger a job every 5 minutes from Start DateTime till End DateTime.

After the job is completed we need to calculate the Next Start DateTime and Next End DateTime and save to the DB -

For this I tried to override the JobListener which has a method: 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);
    }
}

and also the TriggerComplete in the 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);

    }
}

But the problem with above methods is that they are both executed each time the job is called.

So if I have a Job which runs from 12:01 AM and ends 12:02 AM every 5 seconds - Both these methods get called 12 times

What I need is to call a method only once after the One Job iteration has Ended - (After the Job is executed 12 Times)?

How do I do this in Quartz?

EDIT

Creating the Triggers

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;
}

EDIT Trigger with Cron:

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

As you can see from above cron expression it will run from 7 AM to 7:45 AM every 5 minutes every Tuesday and Wednesday.

So 1 iteration is 7AM to 7:45 AM on Tuesday, the Next is 7 AM to 7:45 on Wednesday. I need to call a function after each Iteration has completed.

So let's say that when the Last Trigger is fired for 7:45 AM on Tuesday - I need to call the function.


回答1:


If I understand your problem correctly, you can do this using ITriggerListener in the following way:

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);
    }
}



回答2:


What about creating another job triggered once in a minute for the given period by using the StartTime or EndTime as global values?

In addition to this, you could also check the EndTime value before calling your action method. In this case you execute the action if the current time is equal to or near to DateTime.Now() or something similar to that:

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

Hope this helps...



来源:https://stackoverflow.com/questions/36621113/quartz-net-call-a-function-after-the-job-has-completed-full-execution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!