Bezdepbonusu7Программирование: статьи и ответы

Вопрос

HTTPWebResponse + StreamReader очень медленный

Автор вопроса: RoeyОтветов: 9

Я пытаюсь реализовать ограниченный веб-сканер на С# (только для нескольких сотен сайтов), используя HttpWebResponse.GetResponse() и Streamreader.ReadToEnd() , также пробовал использовать StreamReader.Read() и цикл для создания моей строки HTML.

Я загружаю только страницы размером около 5-10 КБ.

Все очень медленно! Например, среднее время GetResponse() составляет около полсекунды, а среднее время StreamREader.ReadToEnd() - около 5 секунд!

Все сайты должны быть очень быстрыми, так как они находятся очень близко к моему местоположению и имеют быстрые серверы. (в Эксплорере на Д/Л практически ничего не уходит) и никаких прокси я не использую.

Мой Crawler одновременно читает около 20 потоков с одного и того же сайта. Может ли это быть причиной проблемы?

Как резко сократить время StreamReader.ReadToEnd?

performanceweb-crawlerstreamreaderhttpwebresponse

Ответы

Ответ 1 · рейтинг 15 · kgriffs

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

<system.net>
  <defaultProxy enabled="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

Вы также можете увидеть небольшой прирост производительности за счет буферизации ваших операций чтения, чтобы уменьшить количество вызовов, выполняемых к базовому сокету операционной системы:

using (BufferedStream buffer = new BufferedStream(stream))
{
  using (StreamReader reader = new StreamReader(buffer))
  {
    pageContent = reader.ReadToEnd();
  }
}

Ответ 2 · рейтинг 8 · Matt Brindley

DownloadString WebClient - это простая оболочка для HttpWebRequest, не могли бы вы попробовать использовать ее временно и посмотреть, улучшится ли скорость? Если все станет намного быстрее, не могли бы вы поделиться своим кодом, чтобы мы могли посмотреть, что с ним не так?

ИЗМЕНИТЬ:

Кажется, HttpWebRequest наблюдает за параметром "максимальное количество одновременных подключений" IE, эти URL-адреса находятся в одном домене? Вы можете попробовать увеличить лимит подключений, чтобы увидеть, поможет ли это? Я нашел эту статью о проблеме:

По умолчанию вы не можете выполнить более 2-3 асинхронных HttpWebRequest (зависит от ОС). Чтобы переопределить его (самый простой способ, ИМХО), не забудьте добавить этот раздел в конфигурационный файл приложения:

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

Ответ 3 · рейтинг 4 · bisand

У меня была та же проблема, но когда я установил для параметра Proxy HttpWebRequest значение null, это решило проблему.

UriBuilder ub = new UriBuilder(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri );
request.Proxy = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Ответ 4 · рейтинг 1 · No Refunds No Returns

Вы пробовали ServicePointManager.maxConnections? Я обычно устанавливаю его на 200 для вещей, подобных этому.

Ответ 5 · рейтинг 1 · vt2

У меня была такая же проблема, но хуже. ответ = (HttpWebResponse) webRequest.GetResponse(); в моем коде задержалось примерно на 10 секунд, прежде чем запустить дополнительный код, и после этого загрузка переполнила мое соединение.

ответ Курта defaultProxy enabled="false"

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

Ответ 6 · рейтинг 1 · thunder

Я обнаружил, что метод Application Config не работает, но проблема по-прежнему связана с настройками прокси-сервера. Мой простой запрос раньше занимал до 30 секунд, теперь он занимает 1.

public string GetWebData()
{
            string DestAddr = "http://mydestination.com";
            System.Net.WebClient myWebClient = new System.Net.WebClient();
            WebProxy myProxy = new WebProxy();
            myProxy.IsBypassed(new Uri(DestAddr));
            myWebClient.Proxy = myProxy;
            return myWebClient.DownloadString(DestAddr);
}

Ответ 7 · Yuriy

Спасибо всем за ответы, они помогли мне копать в правильном направлении. Я столкнулся с той же проблемой производительности, хотя предложенное решение для изменения файла конфигурации приложения (как я понял, это решение для веб-приложений) не соответствует моим потребностям, мое решение показано ниже:

HttpWebRequest webRequest;

webRequest = (HttpWebRequest)System.Net.WebRequest.Create(fullUrl);
webRequest.Method = WebRequestMethods.Http.Post;

if (useDefaultProxy)
{
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
    webRequest.Credentials = CredentialCache.DefaultCredentials;
}
else
{
    System.Net.WebRequest.DefaultWebProxy = null;
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
}

Ответ 8 · Pangamma

Почему многопоточность не решает эту проблему? Многопоточность сведет к минимуму время ожидания в сети, а поскольку вы будете хранить содержимое буфера в системной памяти (RAM), не будет узких мест ввода-вывода при работе с файловой системой. Таким образом, ваши 82 страницы, загрузка и анализ которых занимает 82 секунды, должны занимать около 15 секунд (при условии 4-кратного процессора). Поправьте меня, если я что-то упустил.

____ СКАЧАТЬ ТЕМУ_____*

Загрузить содержимое

Формировать поток

Читать содержимое

_________________________*

Ответ 9 · ashkufaraz

Попробуйте добавить cookie(AspxAutoDetectCookieSupport=1) к вашему запросу следующим образом

request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы