Quartz JobDataMap传参异常:计划与临时任务无法区分
问题原因与解决方案
问题根源
你直接修改本地job对象的JobDataMap后调用TriggerJob(job.Key)是无效的——Quartz调度器内部已经保存了JobDetail的独立副本,本地修改的对象不会同步到调度器中,因此临时执行时参数无法传递到任务实例里。
正确实现方式
1. 修改临时执行方法AdHocRun
使用TriggerJob的重载方法,直接传入临时JobDataMap,这些参数会绑定到本次触发的临时Trigger上,不会修改原JobDetail的配置:
public void AdHocRun() { JobDataMap adHocParams = new JobDataMap(); adHocParams.Put("Scheduled", false); adHocParams.Put("DT", DL.Format(DateTimeOffset.UtcNow)); // 传入JobKey和临时参数Map quartzScheduler.TriggerJob(job.Key, adHocParams); }
2. 调整任务执行时的参数读取逻辑
临时参数存储在本次触发的Trigger.JobDataMap中,MergedJobDataMap会自动合并JobDetail和Trigger的参数,因此可以直接读取:
... object scheduledTaskObj; // 从Trigger的JobDataMap读取临时参数,不存在则默认是定时执行 bool scheduledTask = context.Trigger.JobDataMap.TryGetValue("Scheduled", out scheduledTaskObj) ? (bool)scheduledTaskObj : true; MessageLogger.LogDebug($"Task scheduled: {scheduledTask}"); // MergedJobDataMap会合并JobDetail和Trigger的参数,同样可以读取 context.MergedJobDataMap.TryGetValue("Scheduled", out scheduledTaskObj); scheduledTask = scheduledTaskObj != null ? (bool)scheduledTaskObj : true; MessageLogger.LogDebug($"[Merged] Task scheduled: {scheduledTask}"); context.Trigger.JobDataMap.TryGetValue("DT", out scheduledTaskObj); MessageLogger.LogDebug($"Date time: {scheduledTaskObj?.ToString()}"); context.MergedJobDataMap.TryGetValue("DT", out scheduledTaskObj); MessageLogger.LogDebug($"[Merged] Date time: {scheduledTaskObj?.ToString()}"); ...
核心逻辑说明
Quartz中JobDetail是不可变配置,一旦被调度器加载后,直接修改本地对象的属性不会同步到调度器。临时执行的参数应该通过触发时传递的方式绑定到本次任务实例,而非修改原JobDetail的JobDataMap。
内容的提问来源于stack exchange,提问作者Metal Paw
相关产品推荐
相关产品推荐

