TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2778 2.71K
День 2303. #ЗаметкиНаПолях
AsyncEnumerable в C#: Важность Атрибута EnumeratorCancellation

Сегодня рассмотрим IAsyncEnumerable<T> и почему атрибут EnumeratorCancellation для параметра CancellationToken имеет решающее значение для написания надёжного отменяемого асинхронного кода.

IAsyncEnumerable<T> — это асинхронный аналог IEnumerable<T> (см. подробнее про создание и потребление асинхронных потоков).

IAsyncEnumerable<T> позволяет:
- Выполнять асинхронные операции во время итерации последовательности;
- Выдавать результаты по мере их появления;
- Обрабатывать отмену.

Необходимость отмены
Поддержка отмены в асинхронных операциях нужна в следующих сценариях:
- Пользователь уходит с веб-страницы, которая извлекает данные;
- Операция поиска занимает слишком много времени, и пользователь отменяет её;
- Сервис завершает работу во время выполнения операций.
Без надлежащей поддержки отмены ресурсы могут быть потрачены впустую, а приложения могут перестать отвечать или произойдёт утечка ресурсов.

Атрибут EnumeratorCancellation
При применении к параметру CancellationToken в методе асинхронного итератора этот атрибут сообщает компилятору о необходимости передать этот токен методу GetAsyncEnumerator, когда итератор используется через await foreach. Вот простой пример:
public async IAsyncEnumerable<int> 
GenerateNumbersAsync(
int count,
[EnumeratorCancellation]
CancellationToken ct = default)
{
for (int i = 0; i < count; i++)
{
// Проверяем отмену
ct.ThrowIfCancellationRequested();

// Симулируем асинхронную работу
await Task.Delay(100, ct);

yield return i;
}
}


Использование метода через вызов WithCancellation:
CancellationTokenSource cts = new();
await foreach (var item in
GenerateNumbersAsync(10)
.WithCancellation(cts.Token))
{
Console.WriteLine(item);
}

Без атрибута EnumeratorCancellation существует разрыв между токеном отмены, переданным в метод асинхронного итератора, и токеном, переданным в GetAsyncEnumerator при потреблении перечисляемого объекта. Атрибут EnumeratorCancellation гарантирует, что этот токен попадёт в метод асинхронного итератора, позволяя вам реагировать на запросы отмены от потребителя.

Чтобы помочь вам избежать этой ошибки, компилятор выдает предупреждение CS8425 в качестве напоминания о правильной реализации отмены в ваших методах асинхронного итератора:
CS8425: Async-iterator method 'MyMethod' has parameters that are declared with 'CancellationToken' but are not decorated with the 'EnumeratorCancellation' attribute, and will not be passed the cancellation token from 'WithCancellation' method calls
CS8425: Метод асинхронного итератора 'MyMethod' имеет параметры, объявленные с 'CancellationToken', но не декорированные атрибутом 'EnumeratorCancellation', и ему не будет передан токен отмены из вызовов метода 'WithCancellation'.


Предупреждение возникает, когда вы определяете метод асинхронного итератора, который возвращает IAsyncEnumerable<T> и включает параметр CancellationToken, но вы не декорировали этот параметр атрибутом [EnumeratorCancellation].

Игнорирование этого предупреждения может привести к неявным ошибкам, когда отмена, кажется, реализована, но на самом деле не работает. Код будет компилироваться и запускаться, но запросы на отмену от потребителей будут игнорироваться.

Итого
При работе с асинхронными потоками:
- Используйте атрибут EnumeratorCancellation для параметров токена отмены;
- Регулярно проверяйте отмену;
- Распространяйте токен на внутренние операции;
- Обратите внимание на предупреждение компилятора CS8425, поскольку оно указывает на потенциальную проблему отмены.

Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html
  • 👍 20
More from @netdeveloperdiary
  1. Oct 3, 2026Post #3360
  2. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
  3. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  4. Oct 1, 2026Post #3357
  5. Sep 30, 2026Post #3356
  6. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
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 →