Telegram Group & Telegram Channel
⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes



tg-me.com/csharp_1001_notes/685
Create:
Last Update:

⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes

BY C# 1001 notes


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/csharp_1001_notes/685

View MORE
Open in Telegram


C 1001 notes Telegram | DID YOU KNOW?

Date: |

Telegram and Signal Havens for Right-Wing Extremists

Since the violent storming of Capitol Hill and subsequent ban of former U.S. President Donald Trump from Facebook and Twitter, the removal of Parler from Amazon’s servers, and the de-platforming of incendiary right-wing content, messaging services Telegram and Signal have seen a deluge of new users. In January alone, Telegram reported 90 million new accounts. Its founder, Pavel Durov, described this as “the largest digital migration in human history.” Signal reportedly doubled its user base to 40 million people and became the most downloaded app in 70 countries. The two services rely on encryption to protect the privacy of user communication, which has made them popular with protesters seeking to conceal their identities against repressive governments in places like Belarus, Hong Kong, and Iran. But the same encryption technology has also made them a favored communication tool for criminals and terrorist groups, including al Qaeda and the Islamic State.

Export WhatsApp stickers to Telegram on iPhone

You can’t. What you can do, though, is use WhatsApp’s and Telegram’s web platforms to transfer stickers. It’s easy, but might take a while.Open WhatsApp in your browser, find a sticker you like in a chat, and right-click on it to save it as an image. The file won’t be a picture, though—it’s a webpage and will have a .webp extension. Don’t be scared, this is the way. Repeat this step to save as many stickers as you want.Then, open Telegram in your browser and go into your Saved messages chat. Just as you’d share a file with a friend, click the Share file button on the bottom left of the chat window (it looks like a dog-eared paper), and select the .webp files you downloaded. Click Open and you’ll see your stickers in your Saved messages chat. This is now your sticker depository. To use them, forward them as you would a message from one chat to the other: by clicking or long-pressing on the sticker, and then choosing Forward.

C 1001 notes from tr


Telegram C# 1001 notes
FROM USA