Приходилось ли писать фоновые задачи по расписанию
Что проверяют
Знаете ли вы средства .NET для фоновой работы и, что важнее, её эксплуатационную сторону: несколько реплик, повторы, идемпотентность, наблюдаемость. Назвать библиотеку мало, спросят, как вы не отправили одно письмо дважды.
Как отвечать
Разложите варианты по весу:
BackgroundServiceвместе сPeriodicTimerвнутри приложения: минимум зависимостей, но расписание не переживает перезапуск;- Hangfire: очередь и расписание в базе, панель, автоматические повторы, удобно, когда задачи часть того же приложения;
- Quartz.NET: гибкое расписание в стиле cron и кластерный режим с блокировками;
- внешний планировщик, запускающий консольное приложение: cron, таймер systemd, задание по расписанию в кластере. Часто самый простой и предсказуемый путь.
Дальше обязательный набор:
CancellationTokenпробрасывается внутрь работы, иначе остановка хоста рвёт задачу посреди транзакции;- тело цикла в try с логированием: необработанное исключение в фоновом сервисе гасит весь хост;
- на каждую итерацию создаётся своя область видимости, контекст базы в синглтоне держать нельзя;
- расписание считается в UTC, иначе перевод часов даёт пропуск или двойной запуск;
- метрика последнего успешного прогона и оповещение, если его давно не было.
Где спотыкаются
Запускают работу через async void или бесконечный цикл без токена отмены. Приложение перестаёт корректно выключаться, а при выкатке задача обрывается на середине.
Второе: получают сервис с ограниченным временем жизни прямо в конструкторе фонового сервиса. В лучшем случае падает на старте, в худшем контекст базы живёт всё время работы процесса и копит отслеживаемые сущности.
Третье: не думают про несколько экземпляров. На двух репликах задача стартует дважды, а повтор после сбоя без идемпотентности шлёт второе письмо или второй платёж. Нужна распределённая блокировка либо ключ операции, по которому повтор распознаётся.