Quartz.NET Running Job Self-Reschedule?

痴心易碎 提交于 2019-12-01 19:53:21

问题


I have created a Quartz.NET job completely programmatically (no config file, etc). It runs on-schedule fine. The job is initialized with a cron string to run every 5 minutes. I would like to have the job change the schedule of itself based on the environment (eg errors happen over time so cron should change to 30 minutes).

I am trying to determine what to write in the

protected override void ExecuteInternal( IJobExecutionContext context )

method so the job "changes itself". Do I set something in the context.Scheduler property? Do I have to go to the Scheduler itself and terminate the job and re-create it (sounds kind of heavy handed to me though)?

All ideas appreciated, thanks.


回答1:


While I haven't used Quartz.NET I have used Quartz in Java projects, and I would think they are similar. I have implemented a solution similar to what you describe. In the executeInteral method you have access to the jobexecution context. Basically it involves the creation of a new trigger and then reschedule the job (rescheduleJob). So when the condition arise you would do something like:

protected void ExecuteInternal( IJobExecutionContext context ) {
  // ... some code
  if (the_condition) {
     // figure out startTime
     // figure out endTime
     // figure out repeat time
     // figoure out repeatInterval
     Trigger trigger = new SimpleTrigger("OurNewTrigger","GROUP_NAME", context.getJobDetail().getName(),context.getJobDetail().getGroup(), startTime, endTime,repeatTime,repeatInterval);
     context.getScheduler().rescheduleJob("OurNewTrigger","GROUP_NAME",trigger);
  }
  // ... some more code
}

Along these lines. Hope this helps.




回答2:


I wanted to run the job in random range of time, between 5 to 25 minute later after last run time, By using this answer (from @skarist) and making some changes on it and using quartz documentation, I solved my problem:

public class YourJob : IJob

{
  public void Execute(IJobExecutionContext context)
  {

    //write your execution code


    //reschedule code after execution code:
     var random = new Random();
     var num = random.Next(5,25);
     var date = DateTime.Now;
     var hour = date.AddMinutes(num).Hour;
     var min = date.AddMinutes(num).Minute;

     ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity(context.Trigger.Key.Name)
        .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(hour, min))
        .StartAt(DateTime.Now)
        .WithPriority(1)
        .Build();

    IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
    scheduler.RescheduleJob(new TriggerKey(context.Trigger.Key.Name), trigger);

    }
}



回答3:


skarist put me on the right track. Including my findings here for the next kid that runs into this.

protected override void ExecuteInternal( IJobExecutionContext jobContext )
{
    // ... do work...
    var tnew = new CronTriggerImpl( #nameofcurrentlyrunningjob# )
    {
        CronExpressionString = "my new cron string is here" ,
        TimeZone = TimeZoneInfo.Utc
    };

    var jobNew = new JobDetailImpl( #nameofcurrentlyrunningjob# , typeof( CurrentJobType ) );

    jobContext.Scheduler.RescheduleJob( new TriggerKey( #nameofcurrentlyrunningjob# ) , tnew );
}

I also added the [DisallowConcurrentExecution] attribute to the class but that's not directly related.



来源:https://stackoverflow.com/questions/24655776/quartz-net-running-job-self-reschedule

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