Task.Parallel.For, похоже, не работает параллельно

#c# #asp.net-mvc #azure

#c# #asp.net-mvc #azure

Вопрос:

Предполагается, что этот фрагмент кода отправляет от 2 до 7 запросов на получение данных одновременно, чтобы сократить время ожидания. На моем компьютере выполнение кода заняло 6 секунд. Когда я загрузил его в Azure, это занимает 60 секунд. Если я открою 2 окна версии Azure и запущу их рядом, они займут 120 секунд. Мне кажется, что они либо не выполняются одновременно, как я хотел, либо что несколько одновременных вызовов являются узким местом на сервере. У кого-нибудь есть какие-нибудь идеи?

 List<string> strs = new List<string>();
Parallel.For(0, uriArray.Count(), index =>
{
    using (var client = new HttpClient())
    {
        var response = client.GetAsync(uriArray[index]).Resu<

        if (response.IsSuccessStatusCode)
        {
            var responseContent = response.Content;
            var responseString = responseContent.ReadAsStreamAsync().Resu<

            using (GZipStream zip = new GZipStream(responseString, CompressionMode.Decompress, true))
            using (StreamReader unzip = new StreamReader(zip))
            {
                strs.Add(unzip.ReadToEnd());
            }
        }
    }
});
  

Комментарии:

1. Сколько ядер у вас на вашем компьютере?

2. @Shyju на моем компьютере 8

3. Как насчет в Azure?

4. Нет особого смысла вызывать асинхронный метод, если вы просто собираетесь заблокировать его, немедленно вызвав Result .

5. @usr Тогда просто вызовите вместо этого синхронные методы. Или действительно не беспокойтесь о параллелизме при выполнении ввода-вывода.

Ответ №1:

Parallel.* Методы предназначены для работы с ЦП, поскольку они используют эвристику на основе ЦП для выбора степени параллелизма. Для работы на основе ввода-вывода эти эвристики полностью завершаются неудачей. Оптимальный DOP для ввода-вывода должен быть определен эмпирически. Это не может быть получено из количества ядер процессора.

виртуальная машина имеет только 1

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

Используйте последний фрагмент кода из https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2 / для обработки ваших рабочих элементов с фиксированной степенью параллелизма. В качестве дополнительного преимущества вы можете потерять .Result вызовы.

В .NET Framework, к сожалению, нет ничего встроенного, поэтому вы должны использовать этот код из блога.