Ответ
В контексте .NET под "шедулером" (scheduler) обычно понимают механизмы для планирования и выполнения асинхронных или отложенных задач. Вот ключевые компоненты:
1. TaskScheduler и SynchronizationContext
Это базовые абстракции, определяющие где и как выполняется код задачи (Task).
- ThreadPool TaskScheduler: По умолчанию задачи выполняются в пуле потоков.
- SynchronizationContext: Позволяет перенаправить продолжение задачи в конкретный контекст (например, в UI-поток с помощью
Dispatcherв WPF илиControl.Invokeв WinForms).
2. Практические инструменты для планирования:
-
Task.Delay: Простой способ асинхронно приостановить выполнение на указанное время, не блокируя поток.await Task.Delay(TimeSpan.FromSeconds(5)); // Асинхронная задержка на 5 секунд -
System.Threading.Timer: Низкоуровневый таймер для периодического выполнения callback-метода в потоке из пула.var timer = new Timer(state => Console.WriteLine("Tick"), null, dueTime: 0, // Запустить сразу period: 1000); // Повторять каждую секунду // Важно: реализовать корректную остановку и dispose. -
IHostedService/BackgroundService(ASP.NET Core): Стандартный способ создания долгоживущих фоновых служб.public class MyBackgroundService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await DoWorkAsync(); await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); } } } -
Сторонние библиотеки: Для сложного планирования (cron-выражения, persistent-хранилище) используют Hangfire или Quartz.NET.
Критически важные практики:
- Всегда используйте
CancellationTokenдля возможности корректной отмены. - В UI-приложениях используйте
TaskScheduler.FromCurrentSynchronizationContext()илиDispatcherдля обновления UI из фоновой задачи. - Для периодических задач в ASP.NET Core предпочтительнее
BackgroundService, а неTimer, так как он интегрирован в жизненный цикл приложения.