简体   繁体   English

在执行POST时,无法将HttpWebRequest超时设置为高于100秒?

[英]Can't set HttpWebRequest timeout higher than 100 seconds when doing a POST?

I am running into an issue where HttpWebRequest won't respect a timeout value higher than 100 seconds when doing a POST. 我遇到了一个问题,HttpWebRequest在执行POST时不会尊重超过100秒的超时值。 However, if the request is a GET, a timeout value higher than 100 seconds is respected. 但是,如果请求是GET,则会遵循高于100秒的超时值。 The timeout exception is thrown at the .GetResponse() call. 在.GetResponse()调用时抛出超时异常。 I'm setting all the timeout values I have been able to discover but it seems I am missing one, or there is a bug in the framework. 我正在设置我能够发现的所有超时值,但似乎我错过了一个,或者框架中有一个错误。

This is a C# app targeting the .NET Framework 3.5, built using Visual Studio 2008. The web server is IIS 6.0 with a connection timeout set to the default 120 seconds, keep-alives enabled... again GET requests respect the timeout value I specify, POST requests respect the timeout if <= 100 seconds. 这是一个针对.NET Framework 3.5的C#应用​​程序,使用Visual Studio 2008构建.Web服务器是IIS 6.0,连接超时设置为默认的120秒,启用了保持活动...再次GET请求尊重超时值I指定,如果<= 100秒,POST请求将遵守超时。

Here is my code: 这是我的代码:

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

When I have set the timeout value to 5 seconds, I will receive a timeout exception after 5 seconds just as one would expect. 当我将超时值设置为5秒时,我将在5秒后收到超时异常,正如人们所期望的那样。 This proves the Timeout value isn't being completely ignored. 这证明Timeout值未被完全忽略。

Has anybody else run into this issue? 还有其他人遇到过这个问题吗? Will using the Async version of GetResponse get around this issue? 使用Async版本的GetResponse会解决这个问题吗? Any and all thoughts welcome, I've been stuck on this for a couple days. 任何和所有的想法都欢迎,我已经坚持了几天。

UPDATE UPDATE

I can get the POST to respect the timeout value if I don't post any data (which isn't very useful). 如果我不发布任何数据(这不是很有用),我可以让POST尊重超时值。 However, as soon as I post any data at all and ContentLength is > 0, it timesout at 100 seconds. 但是,只要我发布任何数据并且ContentLength> 0,它就会超过100秒。 Also, no proxies are involved. 此外,不涉及代理。

UPDATE 2 更新2

Added the POST data to the example and a comment on where NOT to set the Timeout property 将POST数据添加到示例中,并在不设置Timeout属性的位置添加注释

I figured it out. 我想到了。 This is an example of DRY coding coming back and biting me in the butt. 这是一个DRY编码回来并咬我的屁股的例子。 The code above is a paraphrase of my real code, and as such the code above will work fine. 上面的代码是我的真实代码的解释,因此上面的代码将正常工作。

The issue was I was setting the Timeout value after I had already called proxyRequest.GetRequestStream() to add the POST data. 问题是我在调用proxyRequest.GetRequestStream()以添加POST数据后设置了Timeout值。 Because I was setting both the Timeout and ReadWriteTimeout properties, the shortest timeout was winning. 因为我正在设置TimeoutReadWriteTimeout属性,所以最短的超时是赢。 In the case of a POST request, even though the framework let me set the Timeout value AFTER a call to GetRequestStream, it ignored whatever value was set (and instead used the default 100 seconds even though inspecting the Timeout property after setting it showed it was set to what I expected). 在POST请求的情况下,即使框架让我在调用GetRequestStream之后设置Timeout值,它也会忽略设置的任何值(而是使用默认的100秒,即使在设置它之后检查Timeout属性显示它是设置为我所期望的)。 I wish setting the Timeout property worked the same as setting the ReadWriteTimeout property: If you attempt to set the ReadWriteTimeout property after you have called GetRequestStream, it throws an exception. 我希望设置Timeout属性与设置ReadWriteTimeout属性相同:如果在调用GetRequestStream后尝试设置ReadWriteTimeout属性,则会抛出异常。 If Timeout did the same thing, that would have saved me a TON of time. 如果Timeout做了同样的事情,那将节省我一点时间。 I should have caught this sooner, but I'll chalk it up to a learning experience. 我应该早点抓住这个,但我会把它归结为学习经验。

So the moral of the story: Set all the timeout properties for your HttpWebRequest right when you create it. 故事的寓意:在创建HttpWebRequest时立即设置所有超时属性。

Do you have a web proxy between your client and the server? 您的客户端和服务器之间是否有Web代理? Perhaps that's using a timeout itself. 也许那就是使用超时本身。

I suggest you use Wireshark to see what's happening at the network level - and in particular whether anything happens on the network at 100 seconds. 我建议你使用Wireshark来查看网络级别发生了什么 - 特别是网络上是否有任何事情发生在100秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM