← Назад к вопросам
Что произойдет при сбросе CancellationToken?
2.0 Middle🔥 171 комментариев
#Асинхронность и многопоточность
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Реакция на сброс CancellationToken
Когда происходит сброс CancellationToken, это означает, что свойство IsCancellationRequested объекта становится true. Этот сигнал предназначен для кооперативной отмены (cooperative cancellation) — выполнения кода, который может регулярно проверять этот флаг и корректно завершить свою работу, а не для немедленного прерывания потока.
Механизм работы и воздействие
- Изменение состояния токена: Сам токен становится "сброшенным". Все связанные токены (например, созданные через
CancellationTokenSource.CreateLinkedTokenSource) также получают этот сигнал. - Запуск делегатов: Если к токену были зарегистрированы callback-делегаты через метод
Register, они будут выполнены. Это позволяет выполнить дополнительную логику при отмене — например, освобождение ресурсов. - Генерация исключения: При использовании метода
ThrowIfCancellationRequested()в контексте проверяемого кода, если токен сброшен, будет выброшено исключениеOperationCanceledException(илиTaskCanceledExceptionв задачах). Это стандартный способ прервать выполнение с обработкой исключения. - Взаимодействие с Task: Для задач (
Task), которые были созданы с использованием этого токена, будет автоматически произведена отмена, если задача еще не началась или находится в состоянии ожидания. Если задача уже выполняется, она должна самостоятельно проверять токен.
Пример поведения кода при сбросе
Рассмотрим пример задачи, которая реагирует на сброс токена:
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task task = Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
// Проверяем состояние токена
if (token.IsCancellationRequested)
{
// Выполняем корректное завершение
Console.WriteLine("Операция прервана.");
return; // или throw new OperationCanceledException(token);
}
token.ThrowIfCancellationRequested(); // Альтернативный способ
Console.WriteLine($"Шаг {i}");
Thread.Sleep(100);
}
}, token);
// Сброс токена через 500 мс
cts.CancelAfter(500);
try
{
task.Wait();
}
catch (AggregateException ae)
{
ae.Handle(e => e is OperationCanceledException);
Console.WriteLine("Задача была отменена.");
}
При сбросе токена через cts.Cancel() или CancelAfter:
- Токен переходит в состояние
IsCancellationRequested = true. - В теле задачи проверка
token.IsCancellationRequestedилиThrowIfCancellationRequested()приведет к завершению работы (возврату или исключению). - Задача переходит в состояние
Canceled(если завершилась через исключениеOperationCanceledException), что можно проверить черезtask.Status.
Важные особенности и рекомендации
- Не мгновенное прерывание: Сброс токена не прерывает выполнение потока или метода немедленно, как
Thread.Abort. Это лишь сигнал, который должен быть обработан кодом. - Освобождение ресурсов: Используйте регистрацию callback через
Registerдля гарантированного освобождения ресурсов (например, закрытия файлов, сетевых соединений). - Проверка в циклах и длительных операциях: Регулярная проверка токена обязательна в длительных операциях, особенно в циклах или при ожидании внешних ресурсов.
- Исключения и обработка ошибок: Исключение
OperationCanceledExceptionдолжно корректно обрабатываться в вышестоящем коде, чтобы отличать отмену операции от других ошибок. - Связь с async методами: В асинхронных методах токен часто передается как параметр и используется для отмены асинхронных операций, например, в методах
HttpClientили при работе с базами данных.
Таким образом, сброс CancellationToken является центральным механизмом для управления отменой операций в .NET, обеспечивая безопасное и контролируемое завершение работы без риска повреждения состояния программы.