Ответ
CancellationToken — это структура в .NET, предназначенная для безопасной и кооперативной отмены долго выполняющихся или асинхронных операций. Он позволяет передать в метод сигнал о запросе на отмену, а методу — периодически проверять этот сигнал и корректно завершать работу.
Основные компоненты:
CancellationTokenSource: Источник токена. Управляет состоянием отмены через методCancel().CancellationToken: Легковесная структура, которая только отражает состояние отмены. Передается в отменяемые методы.
Базовый пример использования:
public async Task ProcessDataAsync(CancellationToken cancellationToken)
{
// 1. Периодическая ручная проверка
for (int i = 0; i < 100; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // Выбросит OperationCanceledException
// ... выполнение работы на шаге i ...
await Task.Delay(100, cancellationToken); // 2. Автоматическая проверка в поддерживающих API
}
}
// Использование
public async Task MainMethod()
{
using var cts = new CancellationTokenSource();
// Запланировать отмену через 5 секунд, например, по таймауту
cts.CancelAfter(TimeSpan.FromSeconds(5));
try
{
await ProcessDataAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Операция была отменена.");
}
}
Продвинутые сценарии:
- Объединение токенов: Полезно, когда операция должна реагировать на несколько источников отмены (например, пользовательский запрос + общий таймаут приложения).
var userCancellation = new CancellationTokenSource(); var timeoutCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource( userCancellation.Token, timeoutCancellation.Token );
await ProcessDataAsync(linkedCts.Token);
* **Регистрация callback при отмене:**
```csharp
cancellationToken.Register(() =>
{
Console.WriteLine("Токен отменен, выполняется очистка...");
// Освобождение неуправляемых ресурсов и т.д.
});
Важные принципы:
- Отмена является кооперативной. Метод должен сам проверять токен и корректно завершаться.
- После вызова
Cancel()соответствующийCancellationTokenпереходит в состояние "отменен" и больше не может быть использован заново. - Многие API .NET (например,
Task.Delay,HttpClient.SendAsync, EF CoreToListAsync) имеют перегрузки, принимающиеCancellationToken.