Не удается установить время ожидания HttpWebRequest выше 100 секунд при выполнении POST? - PullRequest
11 голосов
/ 21 октября 2011

Я столкнулся с проблемой, когда HttpWebRequest не будет учитывать значение тайм-аута, превышающее 100 секунд при выполнении POST.Однако, если запрос является GET, значение времени ожидания превышает 100 секунд.Исключение тайм-аута выдается при вызове .GetResponse ().Я устанавливаю все значения тайм-аута, которые мне удалось обнаружить, но мне кажется, что я их пропустил, или во фреймворке есть ошибка.

Это приложение C #, предназначенное для .NET Framework 3.5, созданное с использованием Visual Studio 2008. Веб-сервер - IIS 6.0 с тайм-аутом соединения по умолчанию, равным 120 секундам, keep-alives включен ... снова GETзапросы учитывают значение тайм-аута, указанное мной, POST-запросы учитывают тайм-аут, если <= 100 секунд. </p>

Вот мой код:

int timeout = 200000; // 200 seconds
HttpWebRequest proxyRequest = (HttpWebRequest)WebRequest.Create(serverUrl);
proxyRequest.Accept = clientRequest.AcceptTypes.ToDelimitedString(", ");
proxyRequest.Method = "POST"
proxyRequest.UserAgent = clientRequest.UserAgent;
proxyRequest.Timeout =  timeout;
proxyRequest.ReadWriteTimeout = timeout;
proxyRequest.KeepAlive = false;
proxyRequest.AllowAutoRedirect = false;
proxyRequest.ServicePoint.Expect100Continue = false;
proxyRequest.ServicePoint.MaxIdleTime = timeout;
proxyRequest.ServicePoint.ConnectionLeaseTimeout = -1;

try
{
    // add post data
    request.ContentType = "application/x-www-form-urlencoded";
    byte[] postData = Encoding.UTF8.GetBytes("somedata=7&moredata=asdf");
    // set some post data
    request.ContentLength = postData.Length;
    using (Stream stream = request.GetRequestStream())
    {
        stream.Write(postData, 0, postData.Length);
        stream.Close();
    }

    // UPDATE
    // don't set Timeout here! It will be ignored
    // proxyRequest.Timeout = timeout;

    // Timeout exception thrown here if GetResponse doesn't return within 100 seconds
    // even though the Timeout value is set to 200 seconds.
    using (HttpWebResponse proxyResponse = (HttpWebResponse)proxyRequest.GetResponse())
    {
        using (Stream stream = proxyResponse.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(stream, Encoding.Default))
            {
                string content = reader.ReadToEnd();
                [other pointless code for this example]
                reader.Close();
            }
            stream.Close();
        }
        proxyResponse.Close();
    }
}
finally
{
    proxyRequest.Abort();
}

Когда я установил значение тайм-аута на 5 секунд,Через 5 секунд я получу исключение тайм-аута, как и следовало ожидать.Это доказывает, что значение Timeout не полностью игнорируется.

Кто-нибудь еще сталкивался с этой проблемой?Будет ли использование Async версии GetResponse обойти эту проблему?Любые мысли приветствуются, я застрял на этом пару дней.

ОБНОВЛЕНИЕ

Я могу заставить POST соблюдать значение тайм-аута, если я не наденуне публиковать какие-либо данные (что не очень полезно).Однако, как только я публикую какие-либо данные, а ContentLength> 0, время ожидания истекает через 100 секунд.Кроме того, прокси не задействованы.

ОБНОВЛЕНИЕ 2

Добавлены данные POST к примеру и комментарий, где НЕ нужно устанавливать свойство Timeout

Ответы [ 2 ]

22 голосов
/ 28 октября 2011

Я понял это. Это пример СУХОГО кодирования, возвращающегося и кусающего меня в задницу. Код выше является перефразировкой моего реального кода, и, как таковой, код выше будет работать нормально.

Проблема заключалась в том, что я устанавливал значение Timeout после того, как уже вызвал proxyRequest.GetRequestStream () , чтобы добавить данные POST. Поскольку я устанавливал свойства Timeout и ReadWriteTimeout , самый короткий тайм-аут был выигрышным. В случае запроса POST, даже если среда позволяла мне установить значение Timeout ПОСЛЕ вызова GetRequestStream, он игнорировал любое установленное значение (и вместо этого использовал значение по умолчанию 100 секунд, даже если проверка свойства Timeout после установки показала, что это было установить то, что я ожидал). Мне бы хотелось, чтобы настройка свойства Timeout работала так же, как и установка свойства ReadWriteTimeout: если вы попытаетесь установить свойство ReadWriteTimeout после вызова GetRequestStream, оно выдаст исключение. Если бы Timeout сделал то же самое, это сэкономило бы мне тонну времени. Я должен был поймать это раньше, но я записал это на свой счет.

Итак, мораль этой истории: установите все свойства тайм-аута для вашего запроса HttpWebRequest прямо при его создании.

3 голосов
/ 21 октября 2011

Есть ли у вас веб-прокси между вашим клиентом и сервером?Возможно, он использует сам тайм-аут.

Я предлагаю вам использовать Wireshark , чтобы увидеть, что происходит на сетевом уровне - и, в частности, происходит ли что-либо в сети через 100 секунд.

...