Подтвердить что ты не робот

В Quartz.NET есть ли способ установить свойство, которое позволит только одному экземпляру Job работать?

У меня есть служба, которая будет запускаться каждые X минут. Если для какой-то непредвиденной причины эта работа занимает больше времени, чем X минут, я хочу убедиться, что триггер не запускает второй экземпляр этой работы.

Пример сценария

  • У меня есть Job X, захватывает файлы и запускается Quartz каждые 1 минуту.
  • Задание X обычно обрабатывает 100 файлов за 1 минуту, более 100 файлов занимают больше 1 минуты.
  • С момента последнего запуска, 150 файлов случаются там, поэтому Job X запускается и начинает обработку. Когда достигнута 1 минута, было обработано 100 файлов, осталось 50 файлов, а Job X продолжает работать.
  • Однако второй экземпляр Job X стартует, потому что триггер срабатывает каждые 1 минуту.
  • Теперь у меня есть 2 экземпляра Job X, которые собирают те же 50 файлов.

Есть ли способ подключить Quartz.NET, чтобы разрешить только один экземпляр задания? Я в порядке со вторым триггером, ожидающим завершения первого, или я тоже в порядке с возможностью пропустить второй триггер, так как он будет запущен через минуту.



Я взглянул на Java-версию Quartz API и нашел свойство DisallowConcurrentExecution ', но не нашел такого же в .NET. версия.

Мой код для реализации Quartz.NET

public IScheduler Scheduler { get; set; }
public IJobListener AutofacJobListener { get; set; }

public void Start()
{
var trigger = TriggerUtils.MakeMinutelyTrigger(1);
trigger.Name = @"Document Import Trigger";

Scheduler.ScheduleJob(new JobDetail("Document Import", null, typeof(DocumentImportJob)), trigger);
Scheduler.AddGlobalJobListener(AutofacJobListener);
Scheduler.Start();
}
4b9b3361

Ответ 1

Используйте атрибут DisallowConcurrentExecution.

Объявите свой класс следующим образом:

[DisallowConcurrentExecution]
public class SomeTask : IJob
{

} 

Осечка

"Инструкции о пропусках Еще одним важным свойством триггера является его" инструкция о пропусках ". Пропуски пропуска происходят, если постоянный триггер" пропускает "время его увольнения из-за отключения планировщика или потому что нет доступных потоков в пуле потоков Quartz.NET для выполнение задания. Различные типы триггеров имеют разные осечки доступные им инструкции. По умолчанию они используют" умную политику ", инструкция, которая имеет динамическое поведение, основанное на типе триггера и конфигурации. Когда планировщик запускается, он ищет любые постоянные триггеры, которые пропущены, и затем обновляет каждую из они основаны на их индивидуально настроенных инструкциях по пропускам. когда вы начинаете использовать Quartz.NET в своих проектах, вы должны сделать самостоятельно ознакомьтесь с инструкциями по пропускам зажигания, которые определены на данные типы триггеров и объяснены в их документации API. Будет дана более конкретная информация о инструкциях по пропускам в уроках уроков, специфичных для каждого типа триггера."

Ознакомьтесь с информацией "инструкции о пропуске пропусков" в нижней части этих страниц:

Урок 5: SimpleTrigger

Урок 6: CronTrigger

Ответ на старый API Quartz.NET:

http://quartznet.sourceforge.net/apidoc/topic142.html:

Примеры

IStatefulJob следуют немного другим правилам из регулярных Экземпляры IJob. Ключевое различие что связанная с ними JobDataMap повторно сохраняются после каждого выполнения работа, тем самым сохраняя состояние для следующий исполнение. Другая разница заключается в том, что работоспособные задания не допускаются Выполнять одновременно, что означает новые триггеры, которые происходят до завершение метода IJob.Execute будет отложено.

Итак, объявите свой класс "Работа" следующим образом:

class DocumentImportJob : IStatefulJob
{
   ......
} 

Чтобы избежать повторных срабатываний при отложенных задачах сразу после завершения работы (когда задание занимает более 1 минуты и вызывает срабатывание триггера), при создании триггера (ов) выполните следующие действия (отрегулируйте в зависимости от используемого типа триггера ):

myJobTrigger.MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;  

https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/more-about-triggers.html

Ответ 2

В качестве обновления этого ответа в новых версиях Quartz.Net это выполняется с помощью атрибута DisallowConcurrentExecution, который вы применяете к своей работе:

[DisallowConcurrentExecution]
public class MyJob : IJob  
{
    ..
}

И для инструкции о пропуске, вот как это сделать:

var trigger = TriggerBuilder.Create()
    .WithSimpleSchedule(ssb => ssb.WithIntervalInMinutes(interval)
        .RepeatForever()
        .WithMisfireHandlingInstructionIgnoreMisfires()
    )
    .Build();

Ответ 3

Ну, один простой способ сделать это - просто сохранить значение флага в переменной где-нибудь и проверить переменную при входе в метод задания.

Таким образом, вы просто позволите заданию "начать" второй раз, он просто выйдет немедленно, не выполняя никакой реальной работы.

Вот пример:

private volatile bool _IsRunning;

...

if (Interlocked.Exchange(ref _IsRunning, true))
    return;
try
{
    // job code
}
finally
{
    _IsRunning = false;
}

Ответ 4

public bool Validar (контекст IJobExecutionContext)       {

        if (context.Scheduler.GetCurrentlyExecutingJobs().Any(x => x.FireInstanceId != context.FireInstanceId
         && x.JobDetail.Key == context.JobDetail.Key))
        {
            return true;
        }
        else
        {
            return false;
        }

    }