You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quartz.NET JobBuilder复用IJob实例:如何每次执行生成新实例?

问题分析与解决方案

问题根源

你的JobFactory通过[ImportMany(typeof(IJob))]预加载了所有Job实例,MEF在导入这个列表时,会为每个Job类型创建一次实例并存入列表。后续Quartz每次执行Job时,NewJob方法只是从列表中取出已有的实例返回,完全忽略了TestProcessor上[PartCreationPolicy(CreationPolicy.NonShared)]的配置,导致所有Job执行都复用同一个实例,InstanceId自然不会变化。

解决方案

修改JobFactory,放弃预存Job实例列表,改为直接从MEF容器中每次创建新实例,这样就能遵循NonShared的创建策略,实现每次Job执行都生成新实例的需求。

修改后的JobFactory代码:

[Export(typeof(IJobFactory))]
public class JobFactory : IJobFactory
{
    [Import]
    public CompositionContainer Container { get; set; }

    public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        try
        {
            Debug.WriteLine("IDATT.WindowsService.JobFactory - creating new job instance from container");
            // 从MEF容器中获取新的Job实例,遵循NonShared创建策略
            return Container.GetExportedValue<IJob>(bundle.JobDetail.JobType.FullName);
        }
        catch (Exception e)
        {
            var se = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Problem instantiating class '{0}'", bundle.JobDetail.JobType.FullName), e);
            throw se;
        }
    }

    public virtual void ReturnJob(IJob job)
    {
        // 若Job实现了IDisposable,可在此释放资源
        if (job is IDisposable disposableJob)
        {
            Container.ReleaseExport(disposableJob);
        }
    }
}

补充说明

  1. 保留TestProcessor上的[PartCreationPolicy(CreationPolicy.NonShared)]属性,MEF会依据该策略每次创建新实例;
  2. 原有调度代码无需修改,Quartz每次触发Job时都会调用NewJob获取新实例,日志中的InstanceId将每次都不同。

内容的提问来源于stack exchange,提问作者katit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:25:24