Я столкнулся с проблемой, когда HttpWebRequest не соблюдает значение таймаута больше 100 секунд при выполнении POST. Однако, если запрос является GET, значение таймаута более 100 секунд соблюдается. Исключение по таймауту возникает при вызове .GetResponse(). Я устанавливаю все значения тайм-аута, которые мне удалось обнаружить, но, похоже, мне не хватает одного, или в фреймворке есть ошибка.
Это приложение на C#, ориентированное на .NET Framework 3.5, созданное с помощью Visual Studio 2008. Веб-сервер - IIS 6.0 с таймаутом соединения, установленным по умолчанию на 120 секунд, включен режим keep-alives... снова GET-запросы соблюдают указанное мной значение таймаута, POST-запросы соблюдают таймаут, если <= 100 секунд.
Вот мой код:
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 секунд, как и следовало ожидать. Это доказывает, что значение таймаута не игнорируется полностью.
Кто-нибудь еще сталкивался с этой проблемой? Поможет ли использование Async-версии GetResponse решить эту проблему? Любые мысли приветствуются, я застрял на этом уже пару дней.
UPDATE
Я могу заставить POST соблюдать значение таймаута, если я не отправляю никаких данных (что не очень полезно). Однако, как только я размещаю какие-либо данные и ContentLength > 0, таймаут заканчивается через 100 секунд. Также не задействованы прокси.
UPDATE 2
Добавил данные POST в пример и комментарий о том, где НЕ нужно устанавливать свойство Timeout