0Pricing
C# Academy · Урок

Шаблоны CancellationToken и кооперативная отмена

Передавайте CancellationToken и реагируйте на него: создавайте CTS, проверяйте отмену и выбрасывайте исключение, передавайте токен асинхронным API и освобождайте ресурсы с помощью регистраций.

«Шаблоны CancellationToken и кооперативная отмена» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.

Кооперативная отмена

Цель: кооперативно отменять работу.

  • Создайте CancellationTokenSource
  • Передавайте CancellationToken дальше
  • Проверяйте IsCancellationRequested или вызывайте ThrowIfCancellationRequested()
  • Быстро и корректно реагируйте на отмену

Отмена по запросу вызывающего кода

Создайте CancellationTokenSource, передайте токен и отмените операцию из вызывающего кода; вызываемый метод выбросит OperationCanceledException.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static async Task WorkAsync(CancellationToken ct)
  {
    // Poll occasionally; throw to end cooperatively
    for (int i = 0; i < 5; i++)
    {
      ct.ThrowIfCancellationRequested();
      Console.WriteLine("Step " + i);
      await Task.Delay(100, ct); // pass token to async API
    }
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    Task t = WorkAsync(cts.Token);

    // Cancel after a short delay (simulated user action)
    Thread.Sleep(180);
    cts.Cancel();

    try
    {
      t.GetAwaiter().GetResult();
    }
    catch (OperationCanceledException)
    {
      Console.WriteLine("Canceled!");
    }
  }
}

Передача токенов

Передавайте токен через каждый асинхронный слой, чтобы внутренние вызовы могли своевременно остановиться.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static async Task<string> FetchAsync(CancellationToken ct)
  {
    await Task.Delay(80, ct); // pretend I/O
    ct.ThrowIfCancellationRequested();
    return "data";
  }

  static async Task<string> ProcessAsync(CancellationToken ct)
  {
    string raw = await FetchAsync(ct); // forward token
    await Task.Delay(80, ct);
    return raw.ToUpperInvariant();
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    Task<string> job = ProcessAsync(cts.Token);
    cts.CancelAfter(100); // schedule a cancellation
    try
    {
      Console.WriteLine(job.GetAwaiter().GetResult());
    }
    catch (OperationCanceledException)
    {
      Console.WriteLine("Pipeline canceled");
    }
  }
}

Очистка токена через Register

Используйте token.Register, чтобы добавить небольшое действие очистки, выполняемое при поступлении запроса на отмену.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static async Task UseRegistrationAsync(CancellationToken ct)
  {
    using (ct.Register(() => Console.WriteLine("Cleanup: releasing temp resources")))
    {
      for (int i = 0; i < 3; i++)
      {
        ct.ThrowIfCancellationRequested();
        await Task.Delay(120, ct);
        Console.WriteLine("Tick " + i);
      }
    }
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    Task t = UseRegistrationAsync(cts.Token);
    Thread.Sleep(150);
    cts.Cancel();
    try { t.GetAwaiter().GetResult(); }
    catch (OperationCanceledException) { Console.WriteLine("Canceled with cleanup"); }
  }
}

Связанные источники

CreateLinkedTokenSource объединяет несколько сигналов (например, отмену пользователем и тайм-аут) в один токен.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static async Task WorkAsync(CancellationToken ct)
  {
    await Task.Delay(500, ct);
    Console.WriteLine("Finished work");
  }

  public static void Main(string[] args)
  {
    var parent = new CancellationTokenSource();
    var timeout = new CancellationTokenSource();
    timeout.CancelAfter(200);

    // Link both sources: cancel if parent OR timeout requests
    var linked = CancellationTokenSource.CreateLinkedTokenSource(parent.Token, timeout.Token);

    Task t = WorkAsync(linked.Token);
    try { t.GetAwaiter().GetResult(); }
    catch (OperationCanceledException) { Console.WriteLine("Canceled by parent/timeout"); }
    finally { linked.Dispose(); parent.Dispose(); timeout.Dispose(); }
  }
}

Рекомендации

Советы:

  • Передавайте токены в асинхронные API (Task.Delay, операции ввода-вывода), чтобы они своевременно останавливались.
  • Выбрасывайте OperationCanceledException для завершения работы; не подавляйте это исключение.
  • Освобождайте CancellationTokenSource, если он владеет таймерами или регистрациями.
  • Обработчики должны выполняться быстро; в Register выполняйте минимум работы.

Правило кооперативной отмены

Быстрая проверка: каков правильный способ реакции метода на запрос об отмене?

Итоги

Итоги: делайте отмену кооперативной — передавайте токены, проверяйте состояние или вызывайте ThrowIfCancellationRequested, добавляйте небольшую очистку и связывайте источники для объединения сигналов.

Часто задаваемые вопросы

Урок «Шаблоны CancellationToken и кооперативная отмена» бесплатный?

Да — полный текст урока «Шаблоны CancellationToken и кооперативная отмена» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.

Чему я научусь в уроке «Шаблоны CancellationToken и кооперативная отмена»?

Передавайте CancellationToken и реагируйте на него: создавайте CTS, проверяйте отмену и выбрасывайте исключение, передавайте токен асинхронным API и освобождайте ресурсы с помощью регистраций. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 3.

Сколько времени занимает урок «Шаблоны CancellationToken и кооперативная отмена»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблоны CancellationToken и кооперативная отмена
  2. Тайм-ауты, IProgress и асинхронные освобождаемые ресурсы (эмуляция)
  3. Основы устойчивости: повторные попытки и интервалы между ними
← Назад к C# Academy