HttpWebRequest истекло время второго вызова

Почему следующий код Timeout второй (и последующий) раз он запускается?

Код висит на:

using (Stream objStream = request.GetResponse().GetResponseStream())

и затем вызывает исключение WebException, сообщающее, что время запроса истекло.

Я пробовал это с WebRequest а также HttpWebRequest

Редактировать: кажется, код падает в request.GetResponse()

Изменить: этот пост предполагает, что это может быть проблема GC -> http://www.vbforums.com/showthread.php?t=610043 - в соответствии с этим постом проблема смягчается, если Fiddler открыт в фоновом режиме.

Сервер существует и доступен для запросов.

    private string GetQLMResponse(string URL)
    {
        HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
        request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
        request.KeepAlive = false;
        request.Timeout = 5000;
        request.Proxy = null;

        // Read stream
        string responseString = String.Empty;
        try
        {
            using (var response = request.GetResponse())
            {
                using (Stream objStream = response.GetResponseStream())
                {
                    using (StreamReader objReader = new StreamReader(objStream))
                    {
                        responseString = objReader.ReadToEnd();
                        objReader.Close();
                    }
                    objStream.Flush();
                    objStream.Close();
                }
                response.Close();
            }
        }
        catch (WebException ex)
        {
            throw new LicenseServerUnavailableException();
        }
        finally
        {
            request.Abort();
            request = null;
            GC.Collect();
        }
        return responseString;
    }

Брошенный WebException это:

{"Тайм-аут операции"} [System.Net.WebException]: {"Тайм-аут операции"} Данные: {System.Collections.ListDictionaryInternal} HelpLink: null InnerException: null Сообщение: "Тайм-аут операции" Источник: "System" StackTrace: "в System.Net.HttpWebRequest.GetResponse()\r\n в IQX.Licensing.License.GetQLMResponse(строковый URL) в C:\Users\jd\SVN\jd\Products\Development\JAD.Licensing\JAD.Licensing\License.cs: строка 373" TargetSite: {System.Net.WebResponse GetResponse()}


Обновление: ОК. Теперь работает следующий код. ServicePoint устанавливает время ожидания около 4 минут. изменения ServicePoint.ConnectionLeaseTimeout объект запроса означает, что запрос теперь уничтожен через 5000 мс. Спасибо всем за вашу помощь, а также эти 2 страницы:

  1. http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
  2. http://msdn.microsoft.com/en-us/library/6hszazfz(v=VS.80).aspx

    private string GetQLMResponse(string URL)
    {
        HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
        request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);
        request.KeepAlive = false;
        request.Timeout = 5000;
        request.Proxy = null;
    
        request.ServicePoint.ConnectionLeaseTimeout = 5000;
        request.ServicePoint.MaxIdleTime = 5000;
    
        // Read stream
        string responseString = String.Empty;
        try
        {
            using (WebResponse response = request.GetResponse())
            {
                using (Stream objStream = response.GetResponseStream())
                {
                    using (StreamReader objReader = new StreamReader(objStream))
                    {
                        responseString = objReader.ReadToEnd();
                        objReader.Close();
                    }
                    objStream.Flush();
                    objStream.Close();
                }
                response.Close();
            }
        }
        catch (WebException ex)
        {
            throw new LicenseServerUnavailableException();
        }
        finally
        {
            request.Abort();
        }
        return responseString;
    }
    

10 ответов

Решение

Вслед за предыдущими ответами я хотел добавить еще пару вещей. По умолчанию HttpWebRequest разрешает только 2 подключения к одному и тому же хосту (это HTTP 1.1 "любезность"),

Да, это может быть отменено, нет, я не скажу вам, как в этом вопросе, вы должны задать еще один:) Я думаю, что вы должны посмотреть на этот пост.

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

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

Я бы добавил хороший finally {} предложение после вашего перехвата и убедитесь, что, как указано выше, заметки, все потоки сбрасываются, закрываются и ссылки на объект запроса устанавливаются в нуль.

Пожалуйста, дайте нам знать, если это поможет.

WebResponse полученный request.GetReponse() ДОЛЖЕН быть утилизирован должным образом. Попробуйте это (удаление request.Abort() а также GC.Collect() звонки):

using (var wresponse = request.GetResponse())
{
   using (Stream objStream = wresponse.GetResponseStream())
   {
        // ...
   }
}

Изменить: так как он по-прежнему не работает, я предлагаю вам проверить это с пустым приложением Windows. Таким образом, вы могли бы изолировать проблемы app.config или максимальное количество одновременных вызовов для хоста * (используете ли вы другой объект веб-запроса где-то еще в вашем приложении к этому хосту; какой веб-ответ расположен неправильно?).

Надеюсь, что это решит вашу проблему, у меня нет идей!

  • Смотрите ответ Джона Скита здесь.

Как вы уже сказали, запуск fiddler в фоновом режиме уменьшит проблему. Это потому, что сила скрипача закрывает любые ответы. Расширение вышеприведенного поста от Sam B I обеспечит закрытие ответа следующим образом:

using (var wresponse = request.GetResponse())
{
   using (Stream objStream = wresponse.GetResponseStream())
   {
        // ...
   } 
   wresponse.close();
}

Также может быть целесообразно установить для прокси нулевое значение так:

 request.Proxy = Null;

Поскольку.NET Framework будет искать прокси, если вы явно не сделаете этого. Когда fiddler работает, этот эффект будет смягчен, поскольку прокси-сервер fiddlers будет найден напрямую.

Столкнулся с той же проблемой с таймаутами при последующих запросах к серверу, несмотря на правильное удаление / очистку / закрытие всего. попробуйте сбросить группу соединений, у меня сработало:

myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);

также убедитесь, что вы случайно не создаете другие объекты HttpWebRequest/Request в других местах вашего приложения, которые не завершаются должным образом и не удаляются, так как это увеличит количество соединений в точке обслуживания.

У меня была та же проблема, и я решил ее, убедившись, что Abort() метод для каждого объекта запроса создан.

Я прочитал сообщение, помеченное как ответ выше, и это не сработало для меня выше. В итоге я переписал код, используя теги using, и добавил сегмент CloseConnectionGroup, рекомендованный здесь кем-то другим. В конечном итоге код выглядит так:

System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(imageUrl);
                webRequest.AllowWriteStreamBuffering = true;
                webRequest.Timeout = 30000;
                webRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
                webRequest.ServicePoint.MaxIdleTime = 5000;

                using (System.Net.WebResponse webResponse = webRequest.GetResponse())
                {

                    using (System.IO.Stream stream = webResponse.GetResponseStream())
                    {
                        image = System.Drawing.Image.FromStream(stream);
                    }
                }

                webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
                webRequest = null; 
            }

для тех, кто ищет второй тайм-аут в vb.net: убедитесь, что вы использовали:

  1. ответ.закрыть()

  2. ответ.распоряжаться()

после каждого использования вашего веб-ответа.

Случайно ли вы использовали тестовое приложение с именем по умолчанию WindowsFormsAppN? У меня была та же проблема, что я потратил неделю на отладку, потому что она работала в моем производственном коде, а не в простом тестовом решении, которое я создавал. В конце концов, я решил, что это поведение уникально для использования имени решения по умолчанию вместо решения с надлежащим именем.

Изменить: я обнаружил, что моя проблема была связана с использованием BitDefender в качестве моего программного обеспечения AV. Все программы WindowsFormsAppN были заблокированы.

Готово со мной, когда добавляю это

      myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);

Я установил для http время 10 минут, и оно сработало для меня.

Установка на timeout=infinite Это заняло больше времени, и моя программа работала в режиме зависания.

Другие вопросы по тегам