В отличие от Parallel.ForEach, параметр MaxDegreeOfParallelism по умолчанию (согласно документации) получает значение, равное числу ядер, и это логически и теоретически наиболее эффективное число потоков для асинхронного кода. Однако проблема в том, что Parallel.ForEachAsync использует это как количество одновременно обрабатываемых заданий, а не как количество потоков.
C# Concurrency. Асинхронное программирование и многопоточность
·
Нир Добовицки