Эффективная стратегия для выполнения множественных веб-запросов и анализа ответов в parralel - PullRequest
0 голосов
/ 03 октября 2019

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

Теперь мне нужно сделать несколько вызовов для тех, чтобы получить много коллекций, которыеможет быть объединено в один позже. Я думаю, я мог бы выбрать любой из этих Parrallel.ForEach and Tasks.StartNew

. Можете ли вы посоветовать, какой может быть эффективен при обработке этого сценария с обработкой и вычислением веб-запроса.

Ответы [ 2 ]

2 голосов
/ 03 октября 2019

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 дней обучения вы будете уверены, что сможете написать качественный и надежный производственный код. В нем есть все инструменты, необходимые для разделения, объединения, преобразования, буферизации и распараллеливания рабочей нагрузки таким образом, чтобы вы почувствовали, что управляете процессом, не управляя всем на микроуровне.

0 голосов
/ 03 октября 2019

Вы также можете использовать Task.WhenAll ():

    ...
    List<int> list = new List<int> { 1, 2, 3 };
                var listTaks = list.Select(
                            async e => await DoOne(e)
                        );
                var results = await Task.WhenAll(listTaks);
    ...

больше при Task.WhenAll Метод

...