TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2423 2.51K
День 2002. #ЗаметкиНаПолях #Cancellation
Отмена. Часть 3: Обнаружение Отмены. Окончание

Начало

TaskCanceledException
Существует ещё один тип исключения для отмены: TaskCanceledException. Он выбрасывается некоторыми API вместо OperationCanceledException.

Как правило, рекомендуется не использовать TaskCanceledException. Некоторые API просто вызывают OperationCanceledException, даже если они имеют дело с отменёнными задачами. А поскольку TaskCanceledException является производным от OperationCanceledException, код обработчика исключений отмены может просто перехватывать OperationCanceledException, игнорировать TaskCanceledException, и это будет работать везде.

Внимание: не перехватывайте TaskCanceledException. Вместо этого перехватывайте OperationCanceledException.

OperationCanceledException.CancellationToken
OperationCanceledException имеет свойство CancellationToken. Это токен, вызвавший отмену. Это в том случае, если он установлен. Не все API устанавливают это значение для выбрасываемых ими исключений.

Если вашему коду необходимо определить, отменяет ли операцию он сам или это делает какой-то другой код, у вас может возникнуть соблазн использовать это свойство. Но лучше игнорировать его. Когда используются связанные токены отмены (об этом далее в этой серии), вполне возможно, что токен в этом свойстве на самом деле не является основной причиной отмены:
async Task DoSomethingAsync()
{
// Плохой код, не делайте так
using CancellationTokenSource cts = new();

// Создаём что-то, что может отменять cts

try
{
await DoAsync(cts.Token);
}
catch (OperationCanceledException ex)
when (ex.CancellationToken == cts.Token)
{
// Обработка отмены «нашим» токеном
}
}

В коде выше есть проблема: в зависимости от реализации DoAsync возможно, что отмена cts приведёт к тому, что DoAsync выдаст исключение OperationCanceledException, но токен, на который ссылается это исключение, будет отличаться от токена cts.

Если вам действительно необходимо выполнить специальную обработку случая, когда происходит отмена через конкретный токен, попробуйте что-то вроде этого:
async Task DoSomethingAsync()
{
using CancellationTokenSource cts = new();

// Создаём что-то, что может отменять cts

try
{
await DoAsync(cts.Token);
}
catch (OperationCanceledException ex)
when (cts.IsCancellationRequested)
{
// Обработка отмены «нашим» токеном
}
}

Технически, здесь мы проверяем не «привёл ли мой токен к отмене операции», а скорее «произошла ли отмена и запрашивал ли мой токен отмену». Но в подавляющем большинстве случаев такой проверки достаточно.

Внимание: не используйте OperationCanceledException.CancellationToken. Он может работать не так, как вы ожидаете.

Источник: https://blog.stephencleary.com/2022/03/cancellation-3-detecting-cancellation.html
  • 👍 12
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →