Многопоточность и безопасность потоков Quartz.net - PullRequest
0 голосов
/ 05 ноября 2019

Я недавно начал использовать quartz.net, и у меня возник вопрос о безопасности потоков.

public class QuartzService
    {
        public async Task Start()
        {
            // construct a scheduler factory
            NameValueCollection props = new NameValueCollection
            {
                { "quartz.serializer.type", "binary" }
            };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);

            // get a scheduler
            IScheduler sched = await factory.GetScheduler();

            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<TestJob>().StoreDurably()
                .WithIdentity("myJob", "jobGroup1")
                .Build();

            await sched.AddJob(job, true);

            // Trigger the job to run now, and then every 40 seconds
            ITrigger trigger1 = TriggerBuilder.Create()
                .WithIdentity("myTrigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(5)
                    .RepeatForever())
                .ForJob(job)
                .Build();

            // Trigger the job to run now, and then every 40 seconds
            ITrigger trigger2 = TriggerBuilder.Create()
                .WithIdentity("myTrigger2", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(5)
                    .RepeatForever())
                .ForJob(job)
                .Build();

            await sched.ScheduleJob(trigger1);
            await sched.ScheduleJob(trigger2);

            await sched.Start();
        }
    }



 public class TestJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
        }
    }

В приведенном выше примере у меня есть работа с двумя триггерами. У меня вопрос: два триггера совместно используют один и тот же экземпляр задания при запуске? Или каждый раз, когда запускается триггер, создается новый экземпляр IJobDetail. Я пытался прочитать документацию на quartz.net, но это очень запутанно, поскольку он смешивает экземпляры JobDetail с экземпляром задания, и мне не совсем понятно, какова здесь ситуация.

1 Ответ

1 голос
/ 05 ноября 2019

С фабрикой заданий по умолчанию SimpleJobFactory , для каждого вызова задания создается новый экземпляр объекта данного типа задания (тип CLR). По умолчанию экземпляры объекта задания в CLR никогда не разделяются триггерами.

Однако можно создать собственную фабрику заданий, которая может возвращать одиночные сигналы, скажем, из инверсии контейнера управления.

Существует также различие в типе работы. JobDetails описывает тип задания, и несколько триггеров могут указывать на одну и ту же деталь (и, следовательно, на один и тот же тип). Это приводит к тому, что может быть одновременно запущено несколько заданий одного типа CLR , если к заданию не применено PreventConcurrentExecutionAttribute. И чтобы было интересно, PreventConcurrentExecutionAttribute применяется к деталям задания, поэтому две разные детали задания (разные ключи задания), но один и тот же тип, могут снова выполняться одновременно.

...