TGViewer
Библиотека шарписта | C#, F#, .NET, ASP.NET Библиотека шарписта | C#, F#, .NET, ASP.NET @csharpproglib · 21.6K subscribers
Post #6060 4.28K
⚙️ Параллельная асинхронная обработка

В высоконагруженных приложениях часто требуется запустить несколько независимых операций параллельно и дождаться их завершения полностью или частично.

🛠 Дождаться всех задач — Task.WhenAll

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

1. Запускаем задачи параллельно:
var loadUsers   = LoadUsersAsync();   // загрузка списка пользователей
var loadOrders = LoadOrdersAsync(); // загрузка списка заказов
var loadCatalog = LoadCatalogAsync(); // загрузка каталога товаров


2. Ждём завершения всех
await Task.WhenAll(loadUsers, loadOrders, loadCatalog);


3. Получаем результаты
var users   = await loadUsers;   // List<User>
var orders = await loadOrders; // List<Order>
var catalog = await loadCatalog; // List<Product>
Console.WriteLine($"Пользователей: {users.Count}, заказов: {orders.Count}, позиций: {catalog.Count}");


Для задач с возвращаемым значением WhenAll вернёт массив результатов в том же порядке.

Если нужно ограничить количество одновременных операций — обёрните запуск через SemaphoreSlim.

Передавайте CancellationToken во все методы, чтобы можно было прервать все сразу.

🛠 Дождаться первой завершившейся задачи — Task.WhenAny

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

1. Запускаем конкурирующие задачи
var t1 = GetFromCacheAsync(userId, ct);
var t2 = GetFromDatabaseAsync(userId, ct);
var t3 = GetFromApiAsync(userId, ct);


2. Ждём первую завершившуюся
Task<Task<User?>> first = Task.WhenAny(t1, t2, t3);
Task<User?> winner = await first;


3. Получаем и обрабатываем результат

User? user = await winner;  
if (user != null)
Console.WriteLine($"Данные получены от {GetSourceName(winner)}");
else
Console.WriteLine("Пустой ответ от первого источника");


Передавайте единый CancellationToken через CancellationTokenSource, чтобы отменять все задачи разом.

Назначайте разумный таймаут через Task.WhenAny с Task.Delay, чтобы не ждать вечно:
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5), ct);
var winner = await Task.WhenAny(t1, t2, t3, timeoutTask);
if (winner == timeoutTask) throw new TimeoutException();


Для большого числа конкурирующих операций рассматривайте использование Channel или Dataflow вместо запуска сотен Task.

🐸Библиотека шарписта #буст
  • 👍 18
  • 😁 2
  • ❤ 1
  • 👾 1
More from @csharpproglib
  1. Oct 5, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  2. Sep 30, 2026📝 Логирование со строковой интерполяцией Логирование c интерполяцией строк один из самых…
  3. Sep 28, 2026👨‍💻 Не показывайте технические ошибки пользователям Когда приложение падает с необработа…
  4. Sep 26, 2026📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека шарписта #garbage_collector
  5. Sep 25, 2026🔐 NuGet: Microsoft меняет сертификат подписи С 23 сентября Microsoft использует новый сер…
  6. Sep 24, 2026🤩 Как поймать зависший .NET-сервис Приложение начинает тормозить, запросы зависают, а в л…
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 →