Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1286. #ЗаметкиНаПолях #AsyncTips Реагирование на Запросы на Отмену Посредством Периодического Опроса Задача: В коде имеется цикл, который должен поддерживать отмену. Решение Если в коде присутствует цикл обработки, то в нём нет низкоуровневых функций API, которым можно было передать CancellationToken. В этом случае необходимо периодически проверять, не был ли отменён токен. Следующий пример периодически проверяет токен в ходе выполнения цикла, создающего вычислительную нагрузку на процессор:
public int Cancelable(CancellationToken ct)
{
  for (int i = 0; i != 100; ++i)
  {
    Thread.Sleep(1000); // вычисления
    ct.ThrowIfCancellationRequested();
  }
  return 42;
}

Если тело цикла выполняется очень быстро, то, возможно, стоит ограничить частоту проверки токена отмены. Измерьте быстродействие до и после таких изменений, чтобы выбрать лучший вариант. Следующий пример похож на предыдущий, но выполняет больше итераций более быстрого цикла, поэтому добавлено ограничение на частоту проверки маркера:
public int Cancelable(CancellationToken ct)
{
  for (int i = 0; i != 100000; ++i)
  {
    Thread.Sleep(1); // вычисления
    if (i % 1000 == 0)
      ct.ThrowIfCancellationRequested();
  }
  
  return 42;
}

Оптимальная частота опроса зависит исключительно от того, какой объём работы выполняется и насколько быстрой должна быть реакция на отмену. В большинстве случаев ваш код должен просто передать CancellationToken на следующий уровень. Метод периодического опроса (polling), использованный в этом рецепте, следует применять только в том случае, если у вас имеется вычислительный цикл, который должен поддерживать отмену. У типа CancellationToken имеется другой метод IsCancellationRequested, который начинает возвращать true при отмене токена. Некоторые разработчики используют его для реакции на отмену, обычно возвращая значение по умолчанию или null. В большинстве случаев использовать этот метод не рекомендуется. В стандартном паттерне отмены выдаётся исключение OperationCanceledException, для чего вызывается метод ThrowIfCancellationRequested. Если код, находящийся выше в стеке, захочет перехватить исключение и действовать так, словно результат равен null, это нормально, но любой код, получающий CancellationToken, должен следовать стандартному паттерну отмены. Если вы решите не соблюдать паттерн отмены, по крайней мере чётко документируйте свои намерения. Работа метода ThrowIfCancellationRequested основана на периодическом опросе токена отмены; ваш код должен вызывать его с регулярными интервалами. Также существует способ регистрации обратного вызова, который вызывается при запросе на отмену. Об этом в будущих постах. Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 10.