TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #219 548
День сто восемьдесят второй. #ЗаметкиНаПолях
Многопоточность
3. Скоординированная отмена
.NET предлагает стандартный шаблон операций отмены. Он называется скоординированным (cooperative), то есть необходима явная поддержка отмены операций. Это значит, что как код, выполняющий отменяемую операцию, так и код, пытающийся отменить операцию, должны использовать одинаковые типы.
В вызывающем коде создаётся объект CancellationTokenSource. C его помощью можно создать структуру CancellationToken, которая передаётся вызываемому коду. Для отмены операции вызывается метод Cancel объекта CancellationTokenSource.
Вот наиболее полезные члены структуры CancellationToken:
- bool IsCancellationRequested – вызываемый код может периодически обращаться к этому свойству, чтобы узнать, не запрошена ли отмена операции;
- void ThrowIfCancellationRequested() – метод используется в заданиях (Task) аналогично предыдущему свойству;
- CancellationToken None – статическое свойство, обозначающее отсутствие токена отмены, чтобы исключить возможность отмены операции;
- CancellationTokenRegistration Register(…) – метод используется для регистрации одного или нескольких делегатов обратного вызова, которые будут вызваны при отмене операции. Возвращаемая методом структура CancellationTokenRegistration содержит метод Dispose, который позволяет отменить регистрацию.

В примере ниже токен отмены передаётся методу Compute, внутри которого периодически проверяется свойство IsCancellationRequested. Когда пользователь нажимает Enter, вызывается отмена операции, и на следующей итерации цикла он прерывается:
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(o => Compute(cts.Token, 1000));
Console.WriteLine("Нажмите <Enter> для отмены...");
Console.ReadLine();
cts.Cancel();
Console.ReadLine();
}

private static void Compute(CancellationToken token, int countTo)
{
for (int i = 0; i < countTo; i++)
{
if(token.IsCancellationRequested)
{
Console.WriteLine("Счёт отменён");
break;
}
Console.WriteLine(i);
Thread.Sleep(200);
}
Console.WriteLine("Счёт закончен");
}

Продолжение следует…

Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 26.
More from @netdeveloperdiary
  1. Sep 30, 2026Post #3356
  2. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  3. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  4. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  5. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  6. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
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 →