如何在作业执行期间将数据保存到JobDataMap中,并在之后访问它
本文关键字:JobDataMap 之后 访问 保存 作业 执行期 数据 | 更新日期: 2023-09-27 18:20:03
我目前正在围绕Quartz.net开发某种简化的包装器,以便能够管理所有注册和运行的后台作业,显示有关作业执行进度、百分比的其他信息,返回有关当前作业状态的某种消息等。例如,如果我的当前作业正在社交媒体上发布数据,我想看看数据当前发布到哪个社交媒体,或者如果作业正在发送电子邮件,我想实时查看当前生成了多少封电子邮件,已经发送了多少封,还有多少封,等等。为此,我用作业Execute
方法将数据保存到IJobExecutionContext (context.JobDetail.JobDataMap)
。然后使用我的经理获取所有当前正在执行的作业:
public List<IJobExecutionContext> RunningJobs
{
get { return Scheduler.GetCurrentlyExecutingJobs().ToList(); }
}
并显示从每个CCD_ 4的CCD_。这有点管用。但问题是,例如,如果作业执行失败,我希望在JobDataMap
中记录(保存)尽可能多的数据,包括异常对象本身。但是,问题是,当作业执行完成时,上下文对象被丢弃。我丢失了所有的数据。因此,当我尝试获取当前计划作业的所有JobDetail时:
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
的数据但是我仍然可以看到在作业初始化/调度时保存的数据,而不是在实际执行之前。作为一种选择,我可以捕捉异常并在执行过程中记录它(我实际上正在执行),但我想将此作业标记为失败,并在我的"作业"详细信息视图中显示失败原因。它使用List<IJobDetail> AllJobs
(上面实现)从我的经理那里获取数据(这就像我的工作的某种存储库)。
所以我必须使用某种额外的作业详细信息存储来在执行期间保存这些数据,然后获取所有计划的作业,并通过作业ID或其他方式映射这些数据。这不是我更喜欢的解决方案。或者实际上有一种方法可以在执行时将数据保存到JobDataMap,并在执行后访问这些数据
经过一些研究,我发现Quartz中有两种类型的作业:有状态作业和无状态作业(无状态作业)。
有状态作业实例遵循与常规作业实例略有不同的规则。关键的区别在于,它们关联的JobDataMap在每次执行作业后都会重新持久化,从而为下一次执行保留状态。另一个区别是,有状态作业不允许并发执行,这意味着在execute(xx)方法完成之前发生的新触发器将被延迟。
因此,为了实现我的目标,我只需要用PersistJobDataAfterExecution
和DisallowConcurrentExecution
属性来装饰我的作业类,这将使我的作业有状态,并在执行后保持它的JobDataMap。