Максимальное использование циклов Parallel.For или Parallel.Foreach

У меня есть структура вложенных операторов Parallel.For и PLINQ в моем небольшом консольном приложении, которое в основном выполняет сетевые операции (выполнение http-запросов), например:

список пользователей заполняется из БД, где затем я делаю следующее:

Parallel.For(0,users.count(), index=>{

// here I try to perform HTTP requests for multiple users

});

Затем внутри этого цикла for я выполняю оператор plinq для получения информации об этом пользователе через HTTP-запросы.

Итак, теперь я получаю два вложенных цикла, например:

Parallel.For(0,users.count(), index=>{

// Some stuff is done before the PLINQ statement is called... 
newFilteredList.AsParallel().WithDegreeOfParallelism(60).ForAll(qqmethod =>
    {
        var xdocic = new XmlDocument();
        xdocic.LoadXml(SendXMLRequestToEbay(null, null, qqmethod.ItemID, true, TotalDaysSinceLastUpdate.ToString(), null));
        int TotalPages = 0;
        if (xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0) != null)
        {
            TotalPages = Convert.ToInt32(xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0).InnerText);
        }
        if (TotalPages > 1)
        {
            for (int i = 1; i < TotalPages + 1; i++)
            {
                Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), i.ToString()));
            }
        }
        else
        {
            Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), "1"));
        }
    });
});

Я попытался использовать внешний цикл for так же, как и обычный, и заметил, что он работает намного быстрее и лучше, чем этот.

Что меня больше всего беспокоит, так это то, что я проверял загрузку ЦП при запуске консольного приложения, оно всегда составляет около 0,5-3% от общей мощности ЦП...

Таким образом, я пытаюсь выполнить HTTP-запросы следующим образом:

15 пользователей одновременно * количество HTTP-запросов для этих 15 пользователей.

Что я здесь делаю неправильно?


person User987    schedule 31.01.2017    source источник
comment
Классы Parallel не предназначены для работы, не связанной с процессором. HTTP-запросы привязаны к вводу-выводу. Кроме того, каков тип Products, если это просто List<T>, этот класс не является потокобезопасным, и вы нарушаете класс, когда записываете в него несколько потоков одновременно.   -  person Scott Chamberlain    schedule 01.02.2017
comment
@ScottChamberlain Что бы вы посоветовали мне заменить первый внешний цикл for на then ? Я хотел бы иметь возможность обрабатывать 15 и отправлять 15 одновременных HTTP-запросов для этих пользователей, как я могу это сделать?   -  person User987    schedule 01.02.2017
comment
@ScottChamberlain Продукты - это параллельная сумка =)   -  person User987    schedule 01.02.2017
comment
Используйте поток данных вместо этого вы можете иметь два блока в цепочке, один для отправки запроса, один для обработки, вы можете установить максимальную степень параллелизма для каждого блока.   -  person Scott Chamberlain    schedule 01.02.2017
comment
@ScottChamberlain, не могли бы вы мне немного помочь с этим? Как бы я написал практический пример для моего конкретного случая?   -  person User987    schedule 01.02.2017
comment
См. вторую половину этот мой старый ответ содержит два блока: один получает записи параллельно, а другой обрабатывает эти записи по одной, чтобы добавить их в список. вы можете преобразовать 2-й блок, чтобы выполнить необходимую вам обработку, и установить для него более высокую степень параллелизма, чем 1.   -  person Scott Chamberlain    schedule 01.02.2017
comment
Примечание: никакое количество вызовов Parallel.xxx не изменит конфигурацию сети... Вас может больше заинтересовать stackoverflow.com/questions/1361771/   -  person Alexei Levenkov    schedule 01.02.2017