我目前正在开发Quartz.net的某种简化包装器,以便能够管理所有已注册和在后台运行的作业,显示有关作业执行进度,百分比的其他信息,返回有关当前的某些消息例如,如果我当前的工作是将数据发布到社交媒体,我想查看哪些社交媒体是当前发布的数据,或者作业是否正在发送我想要实时的电子邮件< / strong>当前生成了多少封电子邮件,已发送了多少封邮件,剩余了多少封电邮件等。为此,我将作业IJobExecutionContext (context.JobDetail.JobDataMap)
方法中的数据保存到Execute
。然后使用我的经理获取所有当前正在执行的作业:
public List<IJobExecutionContext> RunningJobs
{
get { return Scheduler.GetCurrentlyExecutingJobs().ToList(); }
}
并显示从每个JobDataMap
的{{1}}获取的详细信息。这种方法很好。但问题是,例如,如果作业执行失败,我想在IJobExecutionContext
中记录(保存)尽可能多的数据,包括异常对象本身。但是,问题是,当作业执行完成时,上下文对象被处理掉。我丢失了所有这些数据。因此,当我尝试获取当前计划作业的所有JobDetail时:
JobDataMap
我无法在作业执行期间看到我保存的数据public List<IJobDetail> AllJobs
{
get
{
var result = new List<IJobDetail>();
var jobGroups = Scheduler.GetJobGroupNames();
foreach(string group in jobGroups)
{
var groupMatcher = GroupMatcher<JobKey>.GroupContains(group);
var jobKeys = Scheduler.GetJobKeys(groupMatcher);
foreach(var jobKey in jobKeys)
{
var detail = Scheduler.GetJobDetail(jobKey);
result.Add(detail);
}
}
return result;
}
}
。 但我仍然可以看到作业在实际执行之前初始化/计划时保存的数据。作为一个选项,我可以在执行期间(我实际上正在执行)捕获异常日志,但是我想将此作业标记为失败并在我的作业详细信息视图中显示失败的原因。它使用detail.JobDataMap
(在上面实现)从我的经理(这就像我的工作的某种存储库)中获取数据。
因此,我必须使用某种额外的作业详细信息存储来在执行期间保存此数据,然后获取所有预定作业并按作业ID或其他内容映射此数据。这不是我想要的解决方案。或者实际上有一种方法可以在执行时将数据保存到 JobDataMap 并在执行后访问这些数据?
答案 0 :(得分:4)
经过一番研究后,我发现Quartz中有两种类型的工作:有状态和无状态(非有状态工作)。
有状态作业实例遵循与常规作业实例略有不同的规则。关键的区别在于,每次执行作业后都会重新保存关联的JobDataMap,从而保留下次执行的状态。另一个区别是不允许有状态作业同时执行,这意味着在执行(xx)方法完成之前发生的新触发将被延迟。
因此,要实现我的目标,我必须使用PersistJobDataAfterExecution
和DisallowConcurrentExecution
属性来装饰我的工作类,这将使我的工作成为有状态,并且在执行后它将持久保存它的JobDataMap。