在Quartz.net中处理JobExecutionException

tar*_*tic 20 c# exception-handling quartz.net

可能是一个愚蠢的问题......但无论如何......

我已经设置了quartz,并且可以安排作业,我可以确认作业(实现IJob接口)正在运行.

查看网站上的文档(教程的第3课):

允许从execute方法抛出的唯一异常类型是JobExecutionException.

我希望当发生一个我没有显式处理的异常时,它应该抛出一个JobExecutionException,这样我就可以在'parent'应用程序中记录它.我已经将我的代码包装在try catch中,并且抛出了JobExecutionException,但现在在哪里处理它?

我不会在任何地方调用execute方法,这是由Quartz处理的(在一个单独的线程上).那么,如何在发生错误时处理该错误.我真的不想吞下Job中的错误

Era*_*lel 16

我通过使用基类来捕获所有异常来解决这个问题:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你的Job类应该是这样的:

public class SomeJob : JobBase
{
    public SomeJob()
    {
    }

    public override void ExecuteJob(JobExecutionContext context)
    {
        // Do the actual job here
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案,可以在不同的石英作业中实现通用日志记录。谢谢! (2认同)

jvi*_*lta 12

通常,您将按如下方式设置作业的execute方法:

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
}
Run Code Online (Sandbox Code Playgroud)

此时,调度程序本身会将异常记录到记录的任何位置(基于配置).


Rev*_*1.0 7

如前所述,在全局级别"检测"JobExecutionException的正确方法是实现并注册IJobListener并检查JobWasExecuted()方法中的JobExecutionException参数是否为!= null.

但是,我遇到的问题(从OP的附加评论来看,他也面临这个问题)是Quartz没有处理JobExecutionException(因为它应该),导致一个未处理的异常杀死了应用程序.

到目前为止,我使用的是Quartz.NET 2.0.1发行版(.NET3.5)包中的预编译DLL.为了解决问题的根源,我引用了Quartz项目/源代码,令我惊讶的是它突然工作了?!

作为一个兴趣点,这是执行IJob并处理JobExecutionException 的Quartz库代码:

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...
}
Run Code Online (Sandbox Code Playgroud)

接下来就是直接引用我刚编译的DLL,这也很有用.可悲的是,我无法告诉你为什么这样有效,而且我目前没有时间进一步研究它,但也许这有助于某人.也许其他人可以证实这一点,甚至可以做出解释.它可能与不同的目标平台(x86/64bit)有关?

  • @jvilalta:可能存在误解.引用的代码是Quartz.NET库中的实际代码.不是应用程序的代码.我只是想指出Quartz如何在内部处理JobExecutionException. (4认同)