为什么WebRequest总是在第一个请求上超时,而不会在任何后续请求上超时?

本文关键字:请求 超时 任何 第一个 WebRequest 为什么 | 更新日期: 2023-09-27 18:01:21

有一个问题,调用WebRequest.GetResponse()挂起并在第一次调用时超时,但在第一次调用之后,一切正常

        try {
            WebRequest myHttpWebRequest = WebRequest.Create(@"http://192.168.x.x/");
            // Sends the HttpWebRequest and waits for the response.         
            myHttpWebRequest.Timeout = 1000;
            WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse();
        } catch(Exception e) {
            Console.WriteLine("Failure 1");
        }
        try {
            WebRequest myHttpWebRequest = WebRequest.Create(@"http://192.168.x.x/");
            // Sends the HttpWebRequest and waits for the response.         
            myHttpWebRequest.Timeout = 1000;
            WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse(); 
        } catch(Exception e) {
            Console.WriteLine("Failure 2");
        }
        try {
            WebRequest myHttpWebRequest = WebRequest.Create(@"http://192.168.x.x/");
            // Sends the HttpWebRequest and waits for the response.         
            myHttpWebRequest.Timeout = 1000;
            WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse(); 
        } catch(Exception e) {
            Console.WriteLine("Failure 3");
        }
在控制台应用程序中使用这段代码,我总是收到一个Failure 1。是否在调试器下运行。我已经做了一个1000循环,它总是在第一个失败,从来没有任何其他的。实际上,通过阅读web服务器的日志,它实际上从未接收到第一个请求。我遗漏了什么吗?

为什么WebRequest总是在第一个请求上超时,而不会在任何后续请求上超时?

编辑:我已经意识到下面的答案将适合完全相反的情况,其中第一个请求工作,但其他不。然而,这仍然很重要——你真的应该处理你的回复。如果在报告错误时也报告异常消息,这也会很有用…

要弄清楚这里发生了什么,你真的应该使用像WireShark这样的工具,这样你就可以看到问题是请求被发出但没有响应,还是甚至没有发出请求。

我想知道问题是实际上是,它正在解决代理,或类似的东西…在第二个请求超时之前,有足够的时间来解决它。尝试增加超时时间。同样,这应该可以通过WireShark看到。


您没有处理web响应,因此第二个请求的连接池将超时等待获得该连接。

WebResponse部分放在using语句中,您可能会发现一切都很好:

using (WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse())
{
}
当然,这是假设你真的对响应做了一些事情。否则你可以直接写:
myHttpWebRequest.GetResponse().Dispose();

:)

可能有点晚了,但我有完全相同的效果。最后的原因是,网络中没有默认网关。解决方案是最优地设置请求。Proxy = null.

var request = WebRequest.Create(UriString);
request.Timeout = Timeout;
if (_disableProxy)
{
    request.Proxy = null;
}
if (request is HttpWebRequest)
{
    var response = (HttpWebResponse)request.GetResponse();
    responseStream = response.GetResponseStream();
}
if (request is FtpWebRequest)
{
    var response = (FtpWebResponse)request.GetResponse();
    responseStream = response.GetResponseStream();
}
else if (request is FileWebRequest)
{
    var response = (FileWebResponse)request.GetResponse();
    responseStream = response.GetResponseStream();
}

回复晚了,希望能帮到大家。

我发现我的问题与在新线程中运行HTTP请求有关。由于某种原因,第一个请求总是超时,之后一切正常。我可以看到HTTP请求没有击中服务器,这意味着。net内部的某些东西阻止了它(为了记录,ServicePointManager.DefaultConnectionLimit不是问题)。

我的解决方案是把请求放在Task而不是Thread

(使用。net Framework 4.x)

如果您在请求响应之前没有刷新'关闭RequestStream,则可以得到与此非常相似的行为。这种行为似乎存在于。net 3.5中,但已在。net Framework 4.5中得到解决。我注意到切换框架时的问题——在4.5框架下运行的代码(w/o close)在3.5框架下编译时停止工作。也许可以尝试显式地获取RequestStream并关闭它作为一种解决方案。

我遇到了同样的问题,在我的情况下,我增加了WebRequest对象的timeout值,它工作了!

webRequest.Timeout = int.Parse(60000);

(我已经将timeout属性设置为60秒)