Управлять вызовом JobExecutionException в Quartz.net
Наверное, глупый вопрос... но здесь все равно...
Я установил кварц и могу запланировать задания, и я могу подтвердить, что рабочие задания (реализация интерфейса IJob) работают.
Глядя на документацию на сайте, (Урок 3 учебника):
Единственным типом исключения, которое вы можете бросить из метода execute, является JobExecutionException
.
Мне бы хотелось, чтобы при возникновении исключения, которое я явно не обрабатывал, он должен вызвать исключение JobExecutionException, чтобы я мог зарегистрировать его в "родительском" приложении. Я завернул мой код в try catch и бросил исключение JobExecutionException, но теперь, где его обрабатывать?
Я не вызываю метод execute в любом месте, который обрабатывается Quartz (в отдельном потоке). Итак, как мне обрабатывать эту ошибку, когда она возникает. Я действительно не хочу усвоить ошибку в Job
Ответы
Ответ 1
Как правило, вы должны настроить метод выполнения своей работы следующим образом:
try
{
// the work you want to do goes here
}
catch (ExceptionTypeYouWantToHandle1 ex1)
{
// handle exception
}
catch (ExceptionTypeYouWantToHandle2 ex2)
{
// handle exception
}
// and so on
catch (Exception ex)
{
// something really unexpected happened, so give up
throw new JobExecutionException("Something awful happened", ex, false); // or set to true if you want to refire
}
В этот момент сам планировщик будет регистрировать исключение в любом месте, где он регистрируется (на основе конфигурации).
Ответ 2
Я решил эту проблему, используя базовый класс, чтобы поймать все исключения:
public abstract class JobBase : IJob
{
protected JobBase()
{
}
public abstract void ExecuteJob(JobExecutionContext context);
public void Execute(JobExecutionContext context)
{
string logSource = context.JobDetail.FullName;
try
{
ExecuteJob(context);
}
catch (Exception e)
{
// Log exception
}
}
}
Ваш класс работы должен выглядеть следующим образом:
public class SomeJob : JobBase
{
public SomeJob()
{
}
public override void ExecuteJob(JobExecutionContext context)
{
// Do the actual job here
}
}
Ответ 3
Как уже упоминалось, правильный способ "обнаружить" ExceptionExceptionException на глобальном уровне - реализовать и зарегистрировать IJobListener и проверить, является ли параметр JobExecutionException в методе JobWasExecuted() равным!= null.
Однако проблема, с которой я столкнулся (и, судя по дополнительному комментарию OP, он тоже столкнулся с этим), заключался в том, что Quartz не обрабатывал исключение JobExecutionException (как следует), что привело к необработанному исключению, убивающему приложение.
До сих пор я использовал предварительно скомпилированную DLL из пакета Quartz.NET 2.0.1 (.NET3.5). Чтобы разобраться в сути проблемы, я обратился к проекту Quartz/sourcecode и к моему удивлению, что он внезапно работал?!
В качестве точки интереса это код Quartz library, который выполняет IJob и обрабатывает исключение JobExecutionException:
try {
if (log.IsDebugEnabled) {
log.Debug("Calling Execute on job " + jobDetail.Key);
}
job.Execute(jec);
endTime = SystemTime.UtcNow();
} catch (JobExecutionException jee) {
endTime = SystemTime.UtcNow();
jobExEx = jee;
log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key), jobExEx);
} catch (Exception e) {
// other stuff here...
}
Следующее, что нужно было связать с моей недавно скомпилированной DLL, и это тоже работает. К сожалению, я не могу сказать вам, почему это работает, и у меня нет времени, чтобы попасть в него дальше, но, возможно, это помогает кому-то. Может быть, кто-то еще может подтвердить это и даже дать объяснение. Это может иметь какое-то отношение к различным целевым платформам (x86/64bit)?