【发布时间】:2015-09-17 13:29:26
【问题描述】:
我正在使用 Quartz 调度程序,并尝试在关闭应用程序时关闭所有作业。我有一项专门的工作是“等待”或“忙碌等待”,基本上直到它得到一个条件,它就坐在那里耐心地等待。
由于新的集成点,这项工作是新的。该应用程序使用 Topshelf 作为服务运行,每当我们尝试关闭服务以对其进行升级时,现在该作业正在运行,我们最终必须重新启动服务器以使其关闭。
无论如何,这很奇怪,我只有一个作业类型,当我尝试使用作业FireInstanceId 或JobKey 触发以下代码部分中的中断时:
_logger.InfoFormat("{0} scheduler interrupting listener", scheduler.SchedulerName);
scheduler.Interrupt(ListenerKeys.Realtime);
_logger.InfoFormat("{0} scheduler shutting down", scheduler.SchedulerName);
scheduler.Shutdown(true);
_logger.InfoFormat("{0} scheduler shut down", scheduler.SchedulerName);
我得到一个例外:
Job 'Listeners.Realtime' 不能被中断,因为它没有实现 Quartz.IInterruptableJob
人们会认为这是直截了当的。但是,这是唯一使用此作业密钥的作业:
ListenerJob : BaseJob, IInterruptableJob
{
// some other code referenced in ExecuteJob
public void Interrupt()
{
_dequeuer.StopDequeing();
}
}
我会冒险说这就是你实现它的方式,所以我的问题变成了:Quartz 中是否存在已知的错误?组键和中断是否存在问题?有没有办法告诉调度程序中断所有可中断的作业?有其他选择吗?
更新
我决定运行以下代码以从以下答案中进行更多诊断。 var 接口实际上包含 IInterruptableJob
var jobs = scheduler.GetCurrentlyExecutingJobs().Where(x => Equals(x.JobDetail.Key, ListenerKeys.Realtime));
var job1 = jobs.First();
var interfaces = job1.JobDetail.JobType.GetInterfaces();
此外,我按照下面的建议运行了 ReportInterruptableJob,它检查了程序集并确认 ListenerJob 实现了接口。
更新2:
好的,我去了 git hub,并运行了确切的 meshos。 Job.JobInstance 作为 IInterruptableInterface 返回 null,这就是我收到错误的原因。我想我不明白的是,JobInstance 是如何围绕实现 IInterruptableJob 的 IJo 形成的
UPDATE3:好的....所以我在引导程序中发现了一些使用 JobWrapper 的东西。我对此一无所知,但我确信这是其中的一部分。
【问题讨论】:
-
我曾经有过类似的问题:stackoverflow.com/questions/21537460/…
-
您能否添加某种日志记录机制来查看您的 ListenerJob.Interrupt 方法是否被调用?您可以将其包装在 try catch 中(并登录 catch)以确保方法内的代码不会乱码吗?
-
@granadaCoder 我知道它没有被击中,因为在尝试调用该方法时会引发异常。另外,我在那里留下了一个断点,只是为了仔细检查我的理论并确认它没有被击中。
-
我附加了我的答案............基本上,我发布了一些代码,以便您可以更好地钓鱼以确保假定的 JobKey 确实存在。
标签: c# quartz-scheduler quartz.net