TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #1277 1.45K
День 1043. #ЗаметкиНаПолях #AsyncTips
Использование LINQ с асинхронными потоками
Создание асинхронных потоков
Потребление асинхронных потоков

Задача: обработать асинхронный поток с использованием чётко определенных и хорошо протестированных операторов. Либо использовать LINQ, когда предикат является асинхронным, например, необходимо провести поиск каждого элемента в базе данных или API, чтобы узнать, должен ли он быть включен в итоговую последовательность.

Решение
Допустим, у нас есть метод, производящий асинхронную последовательность:
async IAsyncEnumerable<int> GetAsyncRange()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(100);
yield return i;
}
}

IAsyncEnumerable<T> включает поддержку LINQ в NuGet-пакете System.Linq.Async. Заметьте, что при этом в коде нужно использовать
using static System.Linq.AsyncEnumerable;

Операторы LINQ можно применять к асинхронным потокам. Доступны все знакомые операторы: Where, Select, SelectMany, Join и т.д. Результат представляет собой асинхронный поток:
IAsyncEnumerable<int> values =
GetAsyncRange().Where(value => value % 2 == 0);

await foreach (int result in values) {
Console.WriteLine(result);
}

Но что, если нам нужно передать в Where асинхронный предикат? Where их не поддерживает. Но есть подходящий оператор WhereAwait:
IAsyncEnumerable<int> values = 
GetAsyncRange().WhereAwait(
async value => {
// Асинхронная работа для определения,
// должен ли элемент быть включён в результат
await Task.Delay(10);
return value % 2 == 0;
});

Методы LINQ для асинхронных потоков можно использовать и для обычных перечисляемых объектов, вызвав ToAsyncEnumerable() для любого IEnumerable<T>. Результат можно использовать с WhereAwait, SelectAwait и другими операторами, принимающими асинхронные делегаты.

Операторы LINQ для асинхронных потоков могут оканчиваться суффиксами Async и Await. Операторы, заканчивающиеся суффиксом Async, возвращают обычное значение, допускающее ожидание. Операторы с суффиксом Await получают асинхронный делегат. Т.е. Await в имени подразумевает, что они используют await внутри переданного делегата.

Пример WhereAwait был приведёт выше.

Суффикс Async применяется только к операторам терминации (termination operators), которые извлекают некоторое значение или выполняют некоторые вычисления и возвращают асинхронное скалярное значение. Пример такого оператора — CountAsync, версия Count для асинхронного потока, которая может подсчитать количество элементов, соответствующих некоторому предикату:
int count = await GetAsyncRange()
.CountAsync(value => value % 2 == 0);

Предикат может также быть асинхронным. В этом случае используется метод CountAwaitAsync, поскольку он получает асинхронного делегата и производит одно терминальное значение:
int count = await GetAsyncRange().CountAwaitAsync(
async value => {
await Task.Delay(10);
return value % 2 == 0;
});

Итого
- Операторы без суффиксов (Where, Select) получают синхронные делегаты и выдают асинхронную последовательность.
- Операторы, которые получают асинхронные делегаты, имеют суффикс Await (WhereAwait, SelectAwait), и выдают асинхронную последовательность.
- Операторы, возвращающие терминальное значение, имеют суффикс Async (CountAsync), а также могут иметь суффикс Await, если получают асинхронный делегат (CountAwaitAsync).

Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 3.
More from @netdeveloperdiary
  1. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  2. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  3. Oct 3, 2026Post #3360
  4. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
  5. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  6. Oct 1, 2026Post #3357
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 →