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

Почему этот код WebRequest замедляется?

Я попросил 100 страниц, что все 404. Я написал

    {
    var s = DateTime.Now;
    for(int i=0; i < 100;i++)
        DL.CheckExist("http://google.com/lol" + i.ToString() + ".jpg");
    var e = DateTime.Now;
    var d = e-s;
        d=d;
        Console.WriteLine(d);
    }

static public bool CheckExist(string url)
{
    HttpWebRequest wreq = null;
    HttpWebResponse wresp = null;
    bool ret = false;

    try
    {
        wreq = (HttpWebRequest)WebRequest.Create(url);
        wreq.KeepAlive = true;
        wreq.Method = "HEAD";
        wresp = (HttpWebResponse)wreq.GetResponse();
        ret = true;
    }
    catch (System.Net.WebException)
    {
    }
    finally
    {
        if (wresp != null)
            wresp.Close();
    }
    return ret;
}

Два прогона показывают, что он занимает 00: 00: 30.7968750 и 00: 00: 26.8750000. Затем я попробовал firefox и использовал следующий код

<html>
<body>
<script type="text/javascript">
for(var i=0; i<100; i++)
    document.write("<img src=http://google.com/lol" + i + ".jpg><br>");
</script>

</body>
</html>

Использование моего времени comp и подсчета было примерно 4 секунды. 4 секунды - это 6.5-7.5faster, а затем мое приложение. Я планирую сканировать через тысячи файлов, поэтому принятие 3,75 часов вместо 30 минут будет большой проблемой. Как я могу сделать этот код быстрее? Я знаю, кто-то скажет, что firefox кэширует изображения, но я хочу сказать: 1) он все равно должен проверять заголовки с удаленного сервера, чтобы узнать, обновлено ли это (что я хочу, чтобы мое приложение выполняло) 2) Я не получая тело, мой код должен запрашивать только заголовок. Итак, как я могу это решить?

4b9b3361

Ответ 1

Возможно, Firefox выдает несколько запросов одновременно, тогда как ваш код делает их один за другим. Возможно, добавление потоков ускорит вашу программу.

Ответ 2

Я заметил, что HttpWebRequest зависает при первом запросе. Я сделал некоторые исследования и, похоже, что происходит, что запрос настраивает или автоматически обнаруживает прокси. Если вы установили

request.Proxy = null;

в объекте веб-запроса, вы можете избежать начальной задержки.

С автоматическим определением прокси:

using (var response = (HttpWebResponse)request.GetResponse()) //6,956 ms
{
}

Без автоматического определения прокси:

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

Ответ 3

измените свой код на асинхронный getresponse

public override WebResponse GetResponse() {
    •••
    IAsyncResult asyncResult = BeginGetResponse(null, null);
    •••
    return EndGetResponse(asyncResult);
}

Async Get

Ответ 4

Ответ изменяет HttpWebRequest/HttpWebResponse только на WebRequest/WebResponse. Это устранило проблему.

Ответ 5

Вы пытались открыть тот же URL-адрес в IE на компьютере, на котором развертывается ваш код? Если это компьютер Windows Server, то иногда это происходит потому, что URL-адрес, который вы запрашиваете, не находится в IE (который HttpWebRequest работает) список защищенных сайтов. Вам просто нужно добавить его.

У вас есть дополнительная информация, которую вы можете опубликовать? Я делаю что-то подобное и раньше сталкивался с проблемами HttpWebRequest. Все уникальные. Поэтому больше информации поможет.

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

Ответ 6

закройте поток ответов, когда вы закончите, поэтому в checkExist() добавьте wresp.Close() после wresp = (HttpWebResponse) wreq.GetResponse();

Ответ 7

OK, если вы получаете код статуса 404 для всех веб-страниц, это связано с тем, что вы не указали учетные данные. Поэтому вам нужно добавить

wreq.Credentials = CredentialCache.DefaultCredentials;

Затем вы также можете найти код статуса = 500, для которого вам нужно указать User Agent. Что выглядит примерно так:

wreq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0";

"Экземпляр WebClient по умолчанию не отправляет дополнительные HTTP-заголовки.Если ваш запрос требует дополнительного заголовка, вы должны добавить заголовок в коллекцию Headers. Например, чтобы сохранить запросы в ответе, вы должны добавить пользовательский код, заголовок агента. Кроме того, серверы могут возвращать 500 (Внутренняя ошибка сервера), если отсутствует заголовок агента пользователя."

ссылка: https://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.110).aspx

Чтобы повысить производительность HttpWebrequest, вам нужно добавить

wreq.Proxy=null

теперь код будет выглядеть так:

 static public bool CheckExist(string url)
{
    HttpWebRequest wreq = null;
    HttpWebResponse wresp = null;
    bool ret = false;

try
{
    wreq = (HttpWebRequest)WebRequest.Create(url);
    wreq.Credentials = CredentialCache.DefaultCredentials;
    wreq.Proxy=null;
    wreq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0";
    wreq.KeepAlive = true;
    wreq.Method = "HEAD";
    wresp = (HttpWebResponse)wreq.GetResponse();
    ret = true;
}
catch (System.Net.WebException)
{
}
finally
{
    if (wresp != null)
        wresp.Close();
}
return ret;

}