20

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

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

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

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

我希望当我没有明确处理的异常发生时,它应该抛出一个 JobExecutionException,以便我可以将它记录到“父”应用程序中。我已经将我的代码包装在一个 try catch 中,并抛出了 JobExecutionException,但现在在哪里处理呢?

我不会在任何地方调用 execute 方法,它由 Quartz 处理(在单独的线程上)。那么,当它发生时我该如何处理该错误。我真的不想吞下作业中的错误

4

3 回答 3

18

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

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
        }
    }
}

你的 Job 类应该是这样的:

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

    public override void ExecuteJob(JobExecutionContext context)
    {
        // Do the actual job here
    }
}
于 2011-12-30T22:07:46.853 回答
12

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

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
}

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

于 2011-07-13T04:17:10.433 回答
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...
}

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

于 2012-11-07T08:54:41.273 回答