Подтвердить что ты не робот

HttpWebRequest очень медленный!

Я использую библиотеку с открытым исходным кодом для подключения к моему веб-серверу. Я был обеспокоен тем, что веб-сервер работает очень медленно, а затем я попытался сделать простой тест в Ruby, и я получил эти результаты

Программа Ruby: 2.11 секунды для 10 HTTP GETs

Программа Ruby: 18,13 секунды для 100 HTTP GETs

Библиотека С#: 20.81 секунд для 10 HTTP GETs

Библиотека С#: 36847.46 секунд для 100 HTTP GETs

Я профилировал и нашел проблему такой функцией:

private HttpWebResponse GetRawResponse(HttpWebRequest request) {
  HttpWebResponse raw = null;
  try {
    raw = (HttpWebResponse)request.GetResponse(); //This line!
  }
  catch (WebException ex) {
    if (ex.Response is HttpWebResponse) {
      raw = ex.Response as HttpWebResponse;
    }
  }
  return raw;
}

Отмеченная строка занимает более 1 секунды, чтобы завершить ее самостоятельно, пока программа ruby, выполняющая 1 запрос, занимает 0,3 секунды. Я также делаю все эти тесты на 127.0.0.1, поэтому пропускная способность сети не является проблемой.

Что может стать причиной этого огромного замедления?

UPDATE

Ознакомьтесь с измененными результатами тестов. Я действительно тестировал 10 GET, а не 100, я обновил результаты.

4b9b3361

Ответ 1

То, что я считаю основным виновником медленных веб-запросов, - это свойство прокси. Если вы установите для этого свойства значение null до вызова метода GetResponse, запрос пропустит шаг автоопределения прокси:

request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}

Автообнаружение прокси-сервера занимало до 7 секунд для запроса перед возвратом ответа. Это немного раздражает, что это свойство установлено по умолчанию для объекта HttpWebRequest.

Ответ 2

Возможно, это связано с тем, что вы открываете сразу несколько подключений. По умолчанию максимальное количество открытых HTTP-соединений устанавливается равным двум. Попробуйте добавить это в свой .config файл и посмотреть, помогает ли он:

<system.net>
  .......
  <connectionManagement>
    <add address="*" maxconnection="20"/>
  </connectionManagement>
</system.net>

Ответ 3

У меня была аналогичная проблема с проектом VB.Net MVC.
Локально на моем компьютере (Windows 7) для поиска страниц требовалось менее 1 секунды, но на сервере (Windows Server 2008 R2) для каждого запроса страницы приходилось 20 секунд.

Я попробовал комбинацию настройки прокси-сервера на null

  System.Net.WebRequest.DefaultWebProxy = Nothing
  request.Proxy = System.Net.WebRequest.DefaultWebProxy

И изменив конфигурационный файл, добавив

 <system.net>
   .......
   <connectionManagement>
     <add address="*" maxconnection="20"/>
   </connectionManagement>
 </system.net>

Это все еще не уменьшало медленное время запроса страницы на сервере. В итоге решение заключалось в том, чтобы снять флажок "Автоматически определять настройки" в параметрах IE на самом сервере. (В разделе "Инструменты → Свойства обозревателя" выберите вкладку "Подключения". Нажмите кнопку "Настройки LAN" )

Сразу после того, как я снял флажок с этой опции браузера на сервере, все времена запроса страницы упали с 20 + секунд до менее 1 секунды.

Ответ 4

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

ServicePointManager.DefaultConnectionLimit = 4;

Но после создания этого количества WebRequests задержки вернулись.

Проблема, в моем случае, заключалась в том, что я вызывал POST и не беспокоился об ответе, поэтому не собирался и ничего не делал с ней. К сожалению, это оставило WebRequest плавающим до тех пор, пока они не закончились.

Исправление должно было подобрать ответ и просто закрыть его.

WebRequest webRequest = WebRequest.Create(sURL);
webRequest.Method = "POST";
webRequest.ContentLength = byteDataGZ.Length;
webRequest.Proxy = null;
using (var requestStream = webRequest.GetRequestStream())
{
    requestStream.WriteTimeout = 500;
    requestStream.Write(byteDataGZ, 0, byteDataGZ.Length);
    requestStream.Close();
}
// Get the response so that we don't leave this request hanging around
WebResponse response = webRequest.GetResponse();
response.Close();

Ответ 5

Используйте компьютер, отличный от localhost, а затем используйте WireShark, чтобы увидеть, что действительно происходит через провод.

Как и другие, это может быть несколько вещей. Взгляд на вещи на уровне TCP должен дать четкую картину.

Ответ 6

Я не знаю, как именно я дошел до этого обходного пути, у меня не было времени провести какое-то исследование, так что это зависит от вас, ребята. Там параметр, и я использовал его так (в конструкторе моего класса, перед созданием объекта HTTPWebRequest):

System.Net.ServicePointManager.Expect100Continue = false;

Я не знаю, почему именно, но теперь мои вызовы выглядят довольно быстро.

Ответ 7

Я знаю, что это какой-то старый поток, но я потерял весь день с медленным HttpWebRequest, пробовал каждое предоставленное решение без везения. Каждый запрос по любому адресу составлял более одной минуты.

В конце концов проблема была связана с моим антивирусным брандмауэром (Eset). Я использую брандмауэр с интерактивным режимом, но Eset полностью отключен. Это вызвало просьбу длиться вечно. После включения Eset и выполнения запроса отображается сообщение брандмауэра быстрого доступа и после подтверждения запрос выполняется менее одной секунды.

Ответ 8

Я пробовал все описанные здесь решения без везения, вызов занял около 5 минут.

В чем была проблема: Мне нужен был тот же сеанс и, очевидно, те же файлы cookie (запрос, сделанный на том же сервере), поэтому я восстановил файлы cookie из Request.Cookies в WebRequest.CookieContainer. Время отклика составляло около 5 минут.

Мое решение: Прокомментировал код, связанный с файлом cookie, и bam! Звонок занял менее одной секунды.

Ответ 10

Для меня проблема была в том, что я установил LogMeIn Hamachi - по иронии судьбы, чтобы удаленно отлаживать ту же программу, которая затем начала демонстрировать эту крайнюю медлительность.

К вашему сведению, отключения сетевого адаптера Hamachi оказалось недостаточно, поскольку, похоже, его служба Windows повторно включает адаптер.

Кроме того, повторное подключение к моей сети Hamachi не решило проблему. Только отключение адаптера (путем отключения службы Windows LogMeIn Hamachi) или, возможно, удаление Hamachi, решило проблему для меня.

Можно ли попросить HttpWebRequest выйти через определенный сетевой адаптер?

Ответ 11

У нас была та же проблема в веб-приложении. Мы ждали ответа 5 секунд. Когда мы меняем пользователя на applicationPool на IIS на networkService, ответ начал прибывать менее 1 секунды