繁体   English   中英

Quartz.NET JobBuilder.Create<> 重用相同的 IJob 实例

[英]Quartz.NET JobBuilder.Create<> reuses same instance of IJob

我想为每次执行都有新的 IJob 实例。 这是我的工作设置:

[Export(typeof(IJob))]
[PartCreationPolicy(CreationPolicy.NonShared)]
[DisallowConcurrentExecution]
public class TestProcessor : IJob
{
    [Import]
    public ILoggerService LoggerService { get; set; }
    
    private string InstanceId { get; }

    public TestProcessor()
    {
        this.InstanceId = Guid.NewGuid().ToString().Substring(0, 4);
    }

    public void Execute(IJobExecutionContext context)
    {        
        // TODO: Here I expect to see log entry with different InstanceId every time
        string processGroupId = null;
        if (context != null && context.MergedJobDataMap.ContainsKey(JobListener.ProcessGroupId))
            processGroupId = context.MergedJobDataMap[JobListener.ProcessGroupId].ToString();

        this.LoggerService.Log(null, $"TEST: Group: {processGroupId}, JobInstance: {this.InstanceId}, ServiceInstance: {this.FuelPriceService.InstanceId}", Category.Debug, Priority.Low);
                
    }
}

以下是我如何安排执行此作业。 这里的想法是为不同的“组”运行并发执行,以便这些实例按相同的时间表运行。 但我在所有组的所有日志中看到相同的实例 ID

foreach (var pgId in processGroups)
{    
    // Test Processor
    var testJobDetail = JobBuilder.Create<TestProcessor>().Build();
    testJobDetail.JobDataMap.Add(JobListener.ProcessGroupId, pgId);
    testJobDetail.JobDataMap.Add(JobListener.TimeLimitSeconds, "300");
    
    this.scheduler.ScheduleJob(testJobDetail, TriggerBuilder.Create().WithCronSchedule("0 0/5 * * * ?").Build());
}

我不确定如何

JobBuilder.创建<>()

作品。 它似乎忽略了 MEF 属性并使用了自己的容器? 我希望每次运行 JobBuilder.Create<> 但看不到它时都有新实例。

编辑:更多细节

代码在 windows 服务项目中运行。 在执行代码后的 ServiceBase 构造函数中。 创建这些对象后,我安排了如上所示的作业。 Qauartz.JobBuilder 用于创建它们(不是自定义的)。 没有其他代码,特别是没有关于为 Quartz 配置 MEF 的代码。

// Import job factory 
var jobFactoryInstance = Bootstrapper.CompositionContainer.GetExports<IJobFactory>().FirstOrDefault();
if (jobFactoryInstance == null) throw new InvalidOperationException("Job Factory instance wasn't created!");
var jobFactory = jobFactoryInstance.Value;

// construct a scheduler factory
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
this.scheduler = schedulerFactory.GetScheduler();
this.scheduler.JobFactory = jobFactory;

// Import job listener
var jobListenerInstance = Bootstrapper.CompositionContainer.GetExports<IJobListener>().FirstOrDefault();
if (jobListenerInstance == null) throw new InvalidOperationException();
var jobListener = jobListenerInstance.Value;
this.scheduler.ListenerManager.AddJobListener(jobListener, EverythingMatcher<JobKey>.AllJobs());

EDIT2 :作业工厂详细信息,这只是手动实例化的地方。 看起来这是我需要通过手动创建实例而不是使用预导入列表来提供修复的地方? 听起来我正在回答我的问题..

[Export(typeof(IJobFactory))]
public class JobFactory : IJobFactory
{
    [ImportMany(typeof(IJob))]
    public List<IJob> Jobs { get; private set; }

    public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        try
        {
            Debug.WriteLine("IDATT.WindowsService.JobFactory - getting job from a list");
            return this.Jobs.First(j => j.GetType() == bundle.JobDetail.JobType);
        }
        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)
    {
    }
}

正如您已经发现的那样 - 您有自定义JobBuilder负责创建新的作业实例。 在该构建器中,您有 static 个从 MEF 导入的作业实例列表 ( List<IJob> Jobs ),然后您根据请求的JobType从该列表中获取一个实例。 因此,结果您确实明确地做到了,以便每次都返回TestProcessor的单个实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM