Parrallel.ForEach
и Tasks.StartNew
предназначены для рабочих нагрузок, связанных с ЦП. Для рабочих нагрузок, связанных с вводом / выводом, вам нужна асинхронность, которая наиболее удобно обеспечивается Task.Run(async () => { await ...
Теперь в вашем случае у вас есть рабочие нагрузки, связанные с ЦП и вводом / выводом. Хорошей новостью является то, что асинхронная инфраструктура также хорошо справляется с нагрузками на процессор. Например, это совершенно правильно:
private async void Button1_Click(object sender, EventArgs args)
{
var webData = await GetWebData(url); // I/O bound
var parsedList = await Task.Run(() => ParseWebData(webData)); // CPU bound
await SaveListToDB(parsedList); // I/O bound
}
Во время операций ввода-вывода никакие потоки не будут блокироваться, а поток пула потоков будет выполнять интенсивный анализ ЦП. С точки зрения масштабируемости и сохранения ресурсов, вы не можете сделать намного лучше, чем это. Но если вы хотите связать все ресурсы своей машины, чтобы добиться максимальной производительности, не оставляя ничего свободного для других процессов, тогда ваша стратегия должна состоять в том, чтобы все ваши процессоры / ядра были заняты все время, и в то же времявыполняя максимальное количество одновременных операций ввода-вывода, которые может обработать внешний мир (веб-серверы, файловые системы, базы данных, все имеют ограничения на объем работы, выполняемой одновременно).
Хороший инструмент, на который вам следует обратить вниманиедля реализации этой стратегии используется библиотека TPL Dataflow , встроенная для .NET Core и доступная как пакет для .NET Framework. Если вы ничего не знаете об этом, у него есть некоторая кривая обучения, но не очень крутая. После 2-3 дней обучения вы будете уверены, что сможете написать качественный и надежный производственный код. В нем есть все инструменты, необходимые для разделения, объединения, преобразования, буферизации и распараллеливания рабочей нагрузки таким образом, чтобы вы почувствовали, что управляете процессом, не управляя всем на микроуровне.