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

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

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

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

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

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

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


person Roey    schedule 23.05.2009    source источник


Ответы (9)


arrow_upward
15
arrow_downward

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();
  }
}
person kgriffs    schedule 23.12.2009
comment
Спасибо! Это полностью ускорило мой код с секунд до миллисекунд! - person Cobra_Fast; 13.03.2011
comment
Какой эквивалентный код на C++? Использование (...) не работает в С++ - person Edge; 28.04.2015

arrow_upward
8
arrow_downward

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

ИЗМЕНИТЬ:

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

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

<system.net>
  <connectionManagement>
     <add address="*" maxconnection="65000" />
  </connectionManagement>
</system.net>
person Matt Brindley    schedule 23.05.2009
comment
Пробовал использовать WebClient, результаты те же (среднее время не изменилось). Я также должен упомянуть, что у меня есть соединение 1,5 МБ/с со средней скоростью d/l 180 Кбит/с. Я подумал, что, может быть, 20 потоков, одновременно вызывающих StreamReader.Read, могут иметь какое-то отношение к этому? Или это не имеет значения? - person Roey; 23.05.2009
comment
По моему опыту, при таком соединении вы насыщаете полосу пропускания 3-4 потоками. Нет необходимости запускать больше, если веб-сайты, которые вы пингуете, не очень медленные, а у вас много потоков, ожидающих ввода-вывода. - person kgriffs; 24.12.2009
comment
Вот это да!!! Я использовал асинхронный HttpWebRequest для загрузки тестового сервера примерно с 300 потоками на клиента, и каждый поток загружался последовательно. изменение параметра maxconnection ускорило загрузку данных каждым потоком в 10 раз. - person vivek.m; 25.06.2012

arrow_upward
4
arrow_downward

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

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

arrow_upward
1
arrow_downward

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

person No Refunds No Returns    schedule 14.02.2010

arrow_upward
1
arrow_downward

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

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

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

person vt2    schedule 21.02.2010

arrow_upward
1
arrow_downward

Я обнаружил, что метод 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);
}
person thunder    schedule 24.06.2010

arrow_upward
0
arrow_downward

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

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;
}
person Yuriy    schedule 08.02.2012

arrow_upward
0
arrow_downward

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

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

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

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

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

_________________________*

person Pangamma    schedule 31.12.2014

arrow_upward
0
arrow_downward

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

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