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

发布于 2024-11-19 04:11:33 字数 1417 浏览 6 评论 0原文

遇到问题,调用 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服务器的日志,它实际上从未收到第一个请求。我在这里错过了什么吗?

Having an issue, where calling WebRequest.GetResponse() hangs and times out on the first call, but after the first call, everything works fine.

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

using this code in a console application, I always receive a Failure 1. Running under the debugger or not. I've done a 1000 loop, and it always fails on the first one, never any other ones. In fact, reading the logs of the web server, it actually never receives the first request. Am I missing something here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一页 2024-11-26 04:11:33

编辑:我意识到下面的答案将适合完全相反的情况,其中第一个请求有效,但其他请求无效。然而,它仍然很重要 - 您确实应该处理您的回复。如果当您报告错误时,您还报告异常消息,这也会很有用...

要弄清楚这里发生了什么,您确实应该使用类似 WireShark,以便您可以查看问题是否是已发出请求但未得到响应,或者是否根本没有发出。

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


您不会处理 Web 响应,因此第二个请求的连接池将在等待恢复连接时超时。

WebResponse 部分放入 using 语句中,您可能会发现一切正常:

using (WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse())
{
}

假设您实际上使用当然是回应。否则你可以直接写:

myHttpWebRequest.GetResponse().Dispose();

:)

EDIT: I've realised the answer below would fit with the exact opposite situation, where the first request works but the others don't. However, it's still important - you really should be disposing of your responses. It would also be useful if when you report the error, you also report the exception message...

To work out what's going on here, you should really use something like WireShark so you can see whether the problem is that the request is being made but not responded to, or whether it's not even being made.

I wonder whether the problem is actually that it's resolving a proxy, or something like that... and there's just about enough time to resolve it before the second request times out. Try increasing the timeouts. Again, this should be visible via WireShark.


You're not disposing of the web response, so the connection pool for the second request is going to time out waiting to get that connection back.

Put the WebResponse part in a using statement and you'll probably find it all works fine:

using (WebResponse myHttpWebResponse = myHttpWebRequest.GetResponse())
{
}

That's assuming you'd actually do something with the response, of course. Otherwise you could just write:

myHttpWebRequest.GetResponse().Dispose();

:)

茶底世界 2024-11-26 04:11:33

可能有点晚了,但我得到了完全相同的效果。最终原因是网络中没有默认网关。解决方案是选择性地设置 request.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();
}

希望这有帮助。

May be a little late, but I had exactly the same effect. The reason finally was, that there has been no default gateway in the network. The solution was to optianally set the request.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();
}

Hope this helps.

金兰素衣 2024-11-26 04:11:33

这里回复较晚,但希望对某人有所帮助。

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

我的解决方案是将请求放入 Task 而不是 Thread 中。

(使用.NET Framework 4.x)

Late response here but hopefully it might help someone.

I found my issue related to running the HTTP request in a new thread. For some reason, the first request always timed out and after that, everything was fine. I could see that the HTTP request was not hitting the server which means something internal to .NET was blocking it (for the record, ServicePointManager.DefaultConnectionLimit was not the issue).

The solution for me was to put the request in a Task instead of Thread.

(Using .NET Framework 4.x)

饮惑 2024-11-26 04:11:33

如果在请求响应之前没有刷新/关闭 RequestStream,您可能会得到与此非常相似的行为。此行为似乎存在于 .NET 3.5 上,但已在 .NET Framework 4.5 中得到解决。我在切换框架时注意到了这个问题 - 在 4.5 中工作的代码(没有关闭)在针对 3.5 进行编译时停止工作。也许尝试显式获取 RequestStream 并将其关闭作为解决方法。

You can get a behavior very similar to this if you haven't flushed\closed the RequestStream prior to asking for the Response. This behavior seems to exist on .NET 3.5 but has been addressed in .NET Framework 4.5. I noticed the problem when switching frameworks - code (w/o the close) that worked in 4.5 stopped working when compiled against 3.5. Maybe try explicitly getting the RequestStream and closing it as a work-around.

能否归途做我良人 2024-11-26 04:11:33

我遇到了同样的问题,在我的例子中,我增加了 WebRequest 对象的 timeout 值,并且它起作用了!

webRequest.Timeout = int.Parse(60000);

(我已将超时属性设置为 60 秒)。

I have encountered the same issue, in my case I have increased the timeout value of the WebRequest object and it worked!

webRequest.Timeout = int.Parse(60000);

(I have set the timeout property to 60 Seconds).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文