Parallel.ForEach vs Parallel.ForEachAsync vs Task.WhenAll em C#
Use Parallel.ForEach para trabalho intensivo de CPU sobre dados em memória, Parallel.ForEachAsync para E/S assíncrona sobre muitos itens com um limite de concorrência, e Task.WhenAll para um fan-out fixo e pequeno em que você quer todas as operações em andamento e precisa dos resultados.