Quartz.NET JobBuilder.Create<> повторно использует один и тот же экземпляр 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);
                
    }
}

Вот как я планирую это задание для выполнения. Идея заключается в том, чтобы запускать одновременные выполнения для разных «групп», чтобы эти экземпляры запускались по одному и тому же расписанию. Но я вижу один и тот же идентификатор экземпляра во всех журналах для всех групп.

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 (не пользовательский). Другого кода нет, особенно ничего о настройке MEF для Quartz.

// 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)
    {
    }
}

Можете ли вы проверить это, как создать экземпляр - github.com/quartznet/quartznet/blob/…

Reyan Chougle 23.11.2022 18:00

Вам необходимо предоставить более подробную информацию. По умолчанию JobFactory должен каждый раз создавать новый экземпляр. Вы сказали, что, возможно, он игнорирует MEF, но каким-то образом устанавливает ваш LoggerService?

Evk 25.11.2022 20:53

@Evk да, вы правы, он использует MEF, потому что внедряет службу Logger. Но экземпляр TestProcessor всего один, это моя проблема.

katit 26.11.2022 18:21

Как я уже упоминал, я считаю, что стоит добавить больше кода, например, как вы настраиваете кварц (в частности, как вы настраиваете его для работы с MEF). Может быть, у вас есть пользовательский конструктор заданий?

Evk 26.11.2022 18:54

@Evk - отредактировал сообщение, добавил больше деталей. Похоже, я получил свой ответ, пожалуйста, опубликуйте фактический ответ, чтобы получить награду

katit 28.11.2022 03:39
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
1
5
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как вы уже поняли, у вас есть кастомный JobBuilder, который отвечает за создание новых экземпляров заданий. В этом компоновщике у вас есть статический список экземпляров заданий (List<IJob> Jobs), импортированных из MEF, а затем вы получаете экземпляр из этого списка на основе запрошенного JobType. Итак, в результате вы действительно явно сделали так, чтобы каждый раз возвращался один экземпляр TestProcessor.

Спасибо! Иногда просто нужен другой набор глаз.

katit 28.11.2022 16:42

Другие вопросы по теме