Планирование Фоновых Заданий в Quartz.NET
Если вы создаёте масштабируемое приложение, обычно требуется перенести часть работы в фоновое задание. Несколько примеров:
- отправка email уведомлений,
- создание отчётов,
- обновление кэша,
- обработка изображений.
Quartz.NET — полнофункциональная система планирования заданий с открытым кодом, которую можно использовать от самых маленьких приложений до крупных корпоративных систем.
В Quartz.NET необходимо понимать три концепции:
1. Job — фоновое задание.
2. Trigger — триггер, управляющий запуском задания.
3. Scheduler — планировщик, отвечающий за координацию заданий и триггеров.
Во-первых, добавим пакет Quartz.Extensions.Hosting. Этот вариант установки прекрасно интегрируется с .NET с помощью экземпляра IHostedService.
Теперь надо внедрить и запустить сервис:
services.AddQuartz(cfg =>Quartz.NET будет создавать задания, извлекая их из DI-контейнера. Это также означает, что вы можете использовать scope-сервисы, а не только singleton или transient. Установка WaitForJobsToComplete в true гарантирует, что Quartz.NET будет ожидать корректного завершения заданий перед выходом.
{
cfg.UseMicrosoftDependencyInjectionJobFactory();
});
services.AddQuartzHostedService(opt =>
{
opt.WaitForJobsToComplete = true;
});
Чтобы создать фоновое задание, необходимо реализовать IJob. В нём один метод — Execute, где размещается код фонового задания. Здесь отметим несколько вещей:
- можно использовать DI для внедрения сервисов,
- атрибут DisallowConcurrentExecution предотвращает одновременный запуск задания несколько раз.
[DisallowConcurrentExecution]Теперь зарегистрируем задание в DI-контейнере с триггером (планировщик Quartz создаст сам):
public class ProcessMessages : IJob
{
// внедряем нужные сервисы
public async Task Execute(
IJobExecutionContext context) { … }
}
services.AddQuartz(cfg =>Здесь:
{
var key = new JobKey(nameof(ProcessMessages));
cfg
.AddJob<ProcessMessages>(key)
.AddTrigger(t => t.ForJob(key)
.WithSimpleSchedule(s =>
s.WithIntervalInSeconds(10)
.RepeatForever()
)
);
cfg.UseMicrosoftDependencyInjectionJobFactory();
});
1) Однозначно идентифицируем фоновое задание с помощью JobKey.
2) AddJob регистрирует ProcessMessages в DI, а также в Quartz.
3) Настраиваем триггер для задания, вызывая AddTrigger:
- связываем задание с триггером с помощью ForJob,
- настраиваем расписание: в этом примере запускаем задание каждые десять секунд и повторяем бесконечно, пока работает сервис.
Quartz также поддерживает настройку триггеров с помощью выражений cron.
По умолчанию Quartz настраивает все задания, используя RAMJobStore, который является наиболее производительным, поскольку хранит все данные в оперативной памяти. Однако это также означает, что хранилище непостоянное, и вы можете потерять информацию о планировании, когда приложение остановится или выйдет из строя. Иногда может быть полезно иметь постоянное хранилище, для этого есть встроенный AdoJobStore, который работает с базами данных SQL. Нужно создать набор таблиц базы данных для использования Quartz.NET. Подробности описаны в документации.
Источник: https://www.milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-net