簡體   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