c#-在所有Quartz .NET IInterruptableJob上触发中断
作者:互联网
我正在使用Quartz Scheduler,并尝试在应用程序关闭时关闭所有作业.我有一项专门的工作,它会执行“保持”或“忙碌等待”,基本上会等到出现状况时才耐心等待.
由于有了新的集成点,这项工作是新的.该应用程序是使用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’ can not be interrupted, since it does not implement 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实现了该接口.
UPDATE2:
好的,我去了git hub并运行了确切的Meshos. Job.JobInstance作为IInterruptableInterface返回null,这就是为什么我得到此错误.我不明白的是,我是如何在确实实现IInterruptableJob的IJo周围形成JobInstance的
UPDATE3:好的….因此,我在引导程序中找到了使用JobWrapper<>的内容.我对此一无所知,但我确定这是其中的一部分.
解决方法:
因此,我同意另一个答案(C Knight)的观点,即JobKey可能已关闭.
如果您已经实现了接口…并且您拥有正确的JobKey ..那么您就不应获得该异常.
以下是我中断工作的代码.我也试图找到“ findthekey”逻辑.
private static void InterruptAJob(JobKey foundJobKey, IScheduler sched)
{
if (null != foundJobKey)
{
sched.Interrupt(foundJobKey);
}
}
附加
这是我找到工作钥匙的代码.
我将从它开始……….输入一些断点…,然后查看您的JobKey是否在集合中.也许可以修改例程(在找出魔术位置之后),以根据特定条件查找作业密钥.如果找不到所需的内容,则抛出异常.再说一遍,不要“假设” JobKey存在…..但是查询它并抛出适当的异常(或者,如果找不到匹配项,则编写适当的== null逻辑).假设它必须存在”方法.
再次,下面是“入门”代码…….我的概念证明只从事一项工作,因此我不必具体说明.
private static JobKey FindaJobKey(IScheduler sched, ILogger logger)
{
JobKey returnJobKey = null;
IList<string> jobGroupNames = sched.GetJobGroupNames();
if (null != jobGroupNames)
{
if (jobGroupNames.Count > 0)
{
GroupMatcher<JobKey> groupMatcher = GroupMatcher<JobKey>.GroupEquals(jobGroupNames.FirstOrDefault());
Quartz.Collection.ISet<JobKey> keys = sched.GetJobKeys(groupMatcher);
returnJobKey = keys.FirstOrDefault();
if (null == returnJobKey)
{
throw new ArgumentOutOfRangeException("No JobKey Found");
}
}
}
Thread.Sleep(TimeSpan.FromSeconds(1));
return returnJobKey;
}
附加:
也许是这样的:
private static JobKey FindJobKey(IScheduler sched, ILogger logger, string jobGroupName)
{
JobKey returnJobKey = null;
IList<string> jobGroupNames = sched.GetJobGroupNames();
if (null != jobGroupNames)
{
string matchingJobGroupName = jobGroupNames.Where(s => s.Equals(jobGroupName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (null != matchingJobGroupName)
{
GroupMatcher<JobKey> groupMatcher = GroupMatcher<JobKey>.GroupEquals(matchingJobGroupName);
Quartz.Collection.ISet<JobKey> keys = sched.GetJobKeys(groupMatcher);
if (null != keys)
{
if (keys.Count > 0)
{
throw new ArgumentOutOfRangeException(string.Format("More than one JobKey Found. (JobGroupName='{0}')", jobGroupName));
}
returnJobKey = keys.FirstOrDefault();
if (null != returnJobKey)
{
throw new ArgumentOutOfRangeException(string.Format("No JobKey Found. (JobGroupName='{0}')", jobGroupName));
}
}
}
}
Thread.Sleep(TimeSpan.FromSeconds(1));
return returnJobKey;
}
另一种快速而肮脏的方法“看看发生了什么”.
private static void ShowJobs(IScheduler sched)
{
Console.WriteLine("");
Console.WriteLine("ShowJobs : Start");
GroupMatcher<JobKey> matcherAll = GroupMatcher<JobKey>.AnyGroup();
Quartz.Collection.ISet<JobKey> jobKeys = sched.GetJobKeys(matcherAll);
foreach (JobKey jk in jobKeys)
{
Console.WriteLine(string.Format("{0} : {1}", jk.Group, jk.Name));
}
Console.WriteLine("ShowJobs : End");
Console.WriteLine("");
}
附加:
也许换一种方式.我稍微调整了一种方法.但是增加了一个新的.
ReportIInterruptableJobs
查看什么ReportIInterruptableJobs报告.
private static void ShowJobs(IScheduler sched, ILogger logger)
{
Console.WriteLine("");
Console.WriteLine("ShowJobs : Start");
GroupMatcher<JobKey> matcherAll = GroupMatcher<JobKey>.AnyGroup();
Quartz.Collection.ISet<JobKey> jobKeys = sched.GetJobKeys(matcherAll);
foreach (JobKey jk in jobKeys)
{
Console.WriteLine(string.Format("{0} : {1}", jk.Group, jk.Name));
IJobDetail jobData = sched.GetJobDetail(jk);
if (null != jobData)
{
Console.WriteLine(string.Format("{0}", jobData.JobType.AssemblyQualifiedName));
}
}
Console.WriteLine("ShowJobs : End");
Console.WriteLine("");
}
private static void ReportIInterruptableJobs()
{
Type typ = typeof(IInterruptableJob);
ICollection<Type> types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typ.IsAssignableFrom(p)).ToList();
if (null != types)
{
foreach (Type t in types)
{
Console.WriteLine(string.Format("{0}", t.AssemblyQualifiedName));
}
}
}
标签:quartz-net,quartz-scheduler,c 来源: https://codeday.me/bug/20191027/1947957.html