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

Время ожидания HttpWebRequest при втором вызове

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

Код висит на:

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;
    }

Thrown WebException:

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


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

  • http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
  • 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;
    }
    
4b9b3361

Ответ 1

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

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

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

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

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

Пожалуйста, сообщите нам, если это поможет.

Ответ 2

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

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

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

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

Ответ 3

Как вы уже сказали, запуск скрипача в фоновом режиме смягчит проблему. Это связано с тем, что сила скрипача закрывает любые ответы. Расширяясь на вышеупомянутом посту от Сэма Б, я гарантирую, что ответ будет закрыт так:

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

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

 request.Proxy = Null;

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

Ответ 4

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

myRequest.ServicePoint.CloseConnectionGroup(myRequest.ConnectionGroupName);

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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