Заправить quartz.net триггер через 15 минут, если задание не выполняется с исключением


Я искал ответ о том, как повторно запустить задание после определенного количества времени, если задание создает исключение. Я не вижу никакого простого способа сделать это.

Если я настрою свой триггер следующим образом:

JobDetail job = new JobDetail("Download catalog", null, typeof(MyJob));
job .Durable = true;
Trigger trigger= TriggerUtils.MakeDailyTrigger(12, 0);
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.Name = "trigger name";
scheduler.ScheduleJob(job , trigger);

А моя работа выглядит так:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();


        try
        {
            service.Download();
        }
        catch (Exception)
        {
            throw;
        }

    }
}

Как я могу сделать триггер для повторного запуска после того, как прошло 15 минут, если служба.Вызов Download () вызывает какое-то исключение?

3 13

3 ответа:

Я думаю, что единственный вариант, который у вас есть, - это поймать ошибку и рассказать Quartz.net для немедленного пополнения:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();

        try
        {
            service.Download();
        }
        catch (Exception ex)
        {
              JobExecutionException qe = new JobExecutionException(ex);
              qe.RefireImmediately = true;  // this job will refire immediately
              throw qe;  
        }
    }
}

Вы можете найти некоторую информацию здесь и здесь.

Обновление :

Я провел несколько тестов, и кажется, что вы можете запланировать новый триггер внутри выполняемого задания.
Вы можете попробовать что-то вроде этого:

public class MyJob : IJob
{
    public void Execute(JobExecutionContext context)
    {
        var service = new service();

        try
        {
            service.Download();
        }
        catch (Exception ex)
        {
            JobExecutionException qe = new JobExecutionException(ex);
            // qe.RefireImmediately = true;  // this job will refire immediately
            // throw qe;  
            OnErrorScheduleJob(context);

        }
    }

    private void OnErrorScheduleJob(JobExecutionContext context)
    {
        var jobOnError = context.Scheduler.GetJobDetail("ONERRORJOB", "ERROR");
        if (jobOnError == null)
        {
        JobDetail job = new JobDetail("ONERRORJOB", "ERROR", typeof(MyJob));
        job.Durable = false;
        job.Volatile = false;
        job.RequestsRecovery = false;

        SimpleTrigger trigger = new SimpleTrigger("ONERRORTRIGGER",
                        "ERROR",
                        DateTime.UtcNow.AddMinutes(15),
                        null,
                        1,
                        TimeSpan.FromMinutes(100));

        context.Scheduler.ScheduleJob(job, trigger);     
        }
    }
}

На самом деле, нет необходимости создавать новый JobDetail, как описано LeftyX. Вы можете просто запланировать новый триггер, подключенный к JobDetail из текущего контекста.

public void Execute(JobExecutionContext context) {
    try {
        // code
    } catch (Exception ex) {
        SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl(Guid.NewGuid().ToString());      
        retryTrigger.Description = "RetryTrigger";
        retryTrigger.RepeatCount = 0;
        retryTrigger.JobKey = context.JobDetail.Key;   // connect trigger with current job      
        retryTrigger.StartTimeUtc = DateBuilder.NextGivenSecondDate(DateTime.Now, 30);  // Execute after 30 seconds from now
        context.Scheduler.ScheduleJob(retryTrigger);   // schedule the trigger

        JobExecutionException jex = new JobExecutionException(ex, false);
        throw jex;
    }
}

Это менее подвержено ошибкам, чем создание нового JobDetail. Надеюсь, это поможет.

Я думаю, что правильный ответ-использовать JobListener для повторной попытки задания, как описано здесь: http://thecodesaysitall.blogspot.cz/2012/03/quartz-candy-part-1.html .

В этом решении вы отделяете логику повтора от самого задания, поэтому ее можно использовать повторно.

Если вы реализуете логику повтора в задании, как предложено в другом ответе здесь, она должна быть реализована снова в каждом задании.

Править: Согласно записке Раманприта Сингха, лучшее решение можно найти здесь : https://blog.harveydelaney.com/quartz-job-exception-retrying/