TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #1324 1.51K
День 1074. #ЗаметкиНаПолях #AsyncTips
Параллельное агрегирование

Задача:
требуется агрегировать результаты (суммирование значений или вычисление среднего) при завершении параллельной операции.

Решение
Для поддержки агрегирования класс Parallel использует концепцию локальных значений — переменных, существующих локально внутри параллельного цикла. Это означает, что тело цикла может просто обратиться к значению напрямую, без необходимости синхронизации. Когда цикл готов к агрегированию всех своих локальных результатов, он делает это с помощью делегата localFinally. Следует отметить, что делегату localFinally нужно синхронизировать доступ к переменной для хранения результата. Пример параллельного суммирования:
int ParallelSum(IEnumerable<int> values)
{
int result = 0;
Parallel.ForEach(source: values,
localInit: () => 0,
body: (item, state, localValue) =>
localValue + item,
localFinally: localValue =>
Interlocked.Add(ref result, localValue)
);
return result;
}

В Parallel LINQ реализована более понятная поддержка агрегирования, чем в классе Parallel:
int ParallelSum(IEnumerable<int> values)
{
return values.AsParallel().Sum();
}

На самом деле в PLINQ реализована встроенная поддержка многих распространённых операторов (например, Sum). Также предусмотрена обобщённая поддержка агрегирования с оператором Aggregate:
int ParallelSum(IEnumerable<int> values)
{
return values.AsParallel().Aggregate(
seed: 0,
func: (sum, item) => sum + item
);
}

Если вы уже используете класс Parallel, следует использовать его поддержку агрегирования. В остальных случаях поддержка в PLINQ, как правило, более выразительна, а код получается короче.

UPD: Обновил пример ParallelSum примером из документации с использованием Interlocked.Add вместо lock.

Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 4.
More from @netdeveloperdiary
  1. Oct 15, 2026Post #3374
  2. Oct 14, 2026Post #3373
  3. Oct 13, 2026День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 Почему существует…
  4. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  5. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
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 →