Фоновые задачи (Background tasks)
Начиная с версии 0.9.1 фреймворк стал поддерживать запуск фоновых задач для бота.
Фоновая задача — это независимый процесс, выполняющийся параллельно с основным циклом работы бота. Она не привязана к конкретному входящему событию (сообщению, callback, update) и предназначена для выполнения периодических или длительных операций
За запуск фоновых задач отвечает класс PRBackgroundTaskRunner. Внутри каждого бота стоит свой раннер для фоновых задач.
Доступ к ранеру через сам бот
bot.BackgroundTaskRunnerФоновая задача состоит из двух компонентов.
Интерфейс IPRBackgroundTask - отвечает за выполнения задачи.
Интерфейс IPRBackgroundTaskMetadata - отвечает за метаданные задачи.
Важно ID задачи и метаданных должны быть одинаковы
Фоновая задача
Фоновая задача описывается через интерфейс IPRBackgroundTask.
Она содержит бизнес-логику, которая выполняется по расписанию и работает совместно с метаданными (IPRBackgroundTaskMetadata).
Доступные методы
Id (
Guid) — обязательныйУникальный идентификатор задачи.
Используется для сопоставления задачи и её метаданных, управления выполнением и логирования.
CanExecute() (
Task<bool>) — обязательныйМетод проверяет, может ли задача быть выполнена в текущий момент.
Вызывается перед каждой попыткой запуска задачи.
Возврат
falseозначает, что задача будет пропущена до следующего планового запуска.
ExecuteAsync(CancellationToken cancellationToken) — обязательный
Основной метод, выполняющий бизнес-логику задачи.
cancellationTokenиспользуется для безопасной отмены выполнения задачи.
Initialize(PRBotBase bot) — необязательный
Метод инициализации задачи, вызывается фреймворком перед первым запуском.
Позволяет сохранить экземпляр бота, чтобы получать доступ к его сервисам и контексту.
Если реализация не требует дополнительных действий при инициализации, можно возвращать
Task.CompletedTask.
Примечания
Каждая задача должна иметь уникальный
Id, чтобы правильно сопоставляться с метаданными.Метод
CanExecuteпозволяет динамически контролировать, запускать задачу или пропускать выполнение.Метод
Initializeобычно используется для внедрения зависимостей и получения контекста бота.ExecuteAsyncвыполняется фреймворком в соответствии с настройками из метаданных (IPRBackgroundTaskMetadata).
Метаданные фоновой задачи
Метаданные фоновой задачи описываются через интерфейс IPRBackgroundTaskMetadata.
Они используются для планирования, запуска и контроля выполнения фоновых задач и не содержат бизнес-логику.
Доступные параметры метаданных
Id (
Guid) — обязательныйУникальный идентификатор фоновой задачи.
Используется для сопоставления задачи и её метаданных, а также для управления выполнением (остановка, перезапуск и т.д.).
Name (
string) — обязательныйУникальное имя фоновой задачи.
Применяется для логирования, диагностики и отладки.
BotIds (
HashSet<long>) — необязательныйИдентификаторы ботов, для которых предназначена задача.
Используется для разграничения задач при работе через DI.
Если коллекция пустая или содержит значение
PRConstants.ALL_BOTS_ID, задача применяется ко всем ботам.
InitialDelaySeconds (
int?) — необязательныйЗадержка перед первым запуском задачи (в секундах).
null,0или отрицательное значение — задача запускается немедленно после старта бота.
RepeatSeconds (
int?) — необязательныйИнтервал повторного выполнения задачи (в секундах).
Минимально допустимый интервал повторения — 1 секунда.
MaxRepeatCount (
int?) — необязательныйМаксимальное количество запусков задачи (включая успешные и неуспешные).
nullили-1— неограниченное количество запусков.
MaxErrorAttempts (
int?) — необязательныйМаксимальное количество попыток выполнения задачи при ошибках.
Учитывается первый запуск.
nullили-1— без ограничения.Значение
1означает однократное выполнение без повторных попыток при ошибке.
Примечания
Метаданные могут быть заданы:
через атрибут
PRBackgroundTaskAttribute,через отдельную реализацию
IPRBackgroundTaskMetadata,либо непосредственно в коде при инициализации задач.
При отсутствии метаданных задача не будет запущена, если они не определены иным способом.
Добавление фоновых задач в бота
Фоновые задачи в PRBot можно добавлять двумя способами: через DI (Dependency Injection) или через билдер.
Через DI
Если вы используете контейнер зависимостей (например, Microsoft.Extensions.DependencyInjection), можно зарегистрировать задачи как сервисы:
Пояснения:
Все зарегистрированные сервисы, реализующие
IPRBackgroundTask, будут автоматически подхвачены ботом.AddBackgroundTaskMetadataдобавляет метаданные, если задача не содержит встроенные атрибуты.Задачи через DI позволяют использовать все преимущества контейнера зависимостей (например, логирование, сервисы, базы данных).
Через билдер
Если вы хотите добавить конкретный экземпляр задачи вручную, можно использовать методы AddBackgroundTask:
Пояснения:
Метод
AddBackgroundTask(IPRBackgroundTask)требует, чтобы задача либо имела встроенные метаданные (IPRBackgroundTaskMetadata), либо была помечена атрибутомPRBackgroundTaskAttribute.Метод
AddBackgroundTask(IPRBackgroundTask, IPRBackgroundTaskMetadata)позволяет отдельно указать метаданные для задачи.Метод
AddBackgroundTaskMetadata(IPRBackgroundTaskMetadata)полезен для DI-зависимых задач: сами задачи регистрируются через DI, а метаданные добавляются через билдер.Все задачи, зарегистрированные через билдер, будут подхвачены
PRBackgroundTaskRunnerи выполнены, указанному в метаданных.
Управление текущими и завершенными задачами
Класс PRBackgroundTaskRunner хранит состояние всех фоновых задач бота и предоставляет доступ к информации о текущих (активных) и завершенных задачах.
1. Текущие задачи
Все запущенные задачи хранятся в словаре
ActiveTasks.Ключ —
Guidзадачи, значение — объектIRunningBackgroundTaskData, содержащий:Метаданные задачи (
IPRBackgroundTaskMetadata)Статус выполнения (
PRTaskStatus)Количество выполнений (
ExecutedCount)Количество ошибок (
ErrorCount)Токен отмены (
CancellationTokenSource)
Пример получения всех активных задач:
Завершенные задачи
Все задачи, которые завершились (успешно, с ошибкой или отменой), добавляются в коллекцию
EndTasks.EndTasksсодержит объектыIRunningBackgroundTaskData, где можно узнать:Статус завершения (
CompleteStatus) —Success,FailedилиCanceledДата и время начала и окончания (
StartDate,EndDate)Общее количество выполнений и ошибок
Примеры использования
Остановка конкретной задачи::
Остановка всех задач:
Last updated