Планировщик задач на C# (.NET): от простого таймера до промышленного Quartz.NET
Планировщик задач (Task Scheduler) — неотъемлемая часть любого серьёзного приложения. Будь то периодическая очистка кэша, отправка email-рассылок или синхронизация данных с внешним API — без надёжного механизма выполнения фоновых операций не обойтись. В экосистеме .NET разработчику доступно несколько подходов: от встроенного System.Threading.Timer до мощного и гибкого фреймворка Quartz.NET. В этой статье мы разберём оба варианта, покажем примеры кода и поможем выбрать подходящий инструмент для вашего проекта.
1. Встроенный System.Threading.Timer
Самый простой и лёгкий способ запустить задачу по расписанию — использовать System.Threading.Timer. Он не требует установки сторонних пакетов и идеально подходит для простых сценариев: выполнение метода через фиксированные интервалы или однократная задержка.
Пример: выполнение задачи каждые 5 секунд
using System;
using System.Threading;
class Program
{
static void Main()
{
// Создаём таймер, который запускает callback каждые 5 секунд
Timer timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
Console.WriteLine("Таймер запущен. Нажмите Enter для выхода.");
Console.ReadLine();
timer.Dispose();
}
static void DoWork(object state)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Выполнение фоновой задачи...");
}
}
Плюсы:
- Встроен в .NET, не нужны дополнительные библиотеки.
- Минимальное потребление ресурсов.
- Простота использования.
Минусы:
- Нет встроенной поддержки CRON-выражений.
- Сложно управлять несколькими задачами с разными расписаниями.
- Нет механизмов персистентности (задачи теряются при перезапуске).
- Callback выполняется в потоке из пула, возможны проблемы с синхронизацией.
Для учебных проектов и простых утилит System.Threading.Timer — отличный выбор. Однако для production-приложений с десятками задач стоит присмотреться к более продвинутым решениям.
2. Quartz.NET — промышленный планировщик задач
Quartz.NET — это мощный, гибкий и зрелый фреймворк для планирования задач в .NET. Он вдохновлён популярным Java-аналогом Quartz и поддерживает:
- CRON-выражения для гибкого расписания (каждый второй час, по будням в 9:00 и т.д.).
- Персистентность задач (сохранение в БД).
- Кластеризацию (несколько серверов могут выполнять задачи).
- Пропущенные задачи (misfire handling).
- Дочерние задачи и триггеры.
Установка Quartz.NET
Установите пакет через NuGet:
dotnet add package Quartz
Пример: простая задача с CRON-расписанием
using System;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
class Program
{
static async Task Main()
{
// Создаём планировщик
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();
// Определяем задачу (Job)
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("helloJob", "group1")
.Build();
// Создаём триггер: каждый день в 10:30 утра
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.WithCronSchedule("0 30 10 ? * * *") // CRON: секунда, минута, час, день, месяц, день недели
.Build();
// Регистрируем задачу с триггером
await scheduler.ScheduleJob(job, trigger);
Console.WriteLine("Планировщик запущен. Нажмите Enter для выхода.");
Console.ReadLine();
await scheduler.Shutdown();
}
}
// Класс, реализующий логику задачи
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync($"[{DateTime.Now:HH:mm:ss}] Привет от Quartz.NET!");
}
}
CRON-выражение: разбор примера
В примере "0 30 10 ? * * *" означает:
- 0 — секунда (0).
-
Также в библиотеке
Отправка email на Kotlin: библиотеки и примеры кода
Геолокация и карты в C# (.NET): библиотеки, примеры и рекомендации
Авторизация и аутентификация в Swift (iOS/macOS): полное руководство
Отправка email на Kotlin: библиотеки, примеры и настройка SMTP
AngleSharp для C# (.NET): полное руководство с примерами
Рекомендаций