Заправить 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 ответа:
Я думаю, что единственный вариант, который у вас есть, - это поймать ошибку и рассказать 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/