Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does WebRequest timeout always on the first request, but never on any subsequent ones

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?

like image 927
Rahly Avatar asked Jul 07 '11 12:07

Rahly


People also ask

What is the default timeout for Webrequest C#?

The default value is 100,000 milliseconds (100 seconds).

How does Web API handle timeout exception?

If you really need to implement a timeout on the API side itself, I would recommend creating a thread to do your work in, and then cancelling it after a certain period. You could for example put it in a Task , create your 'timeout' task using Task. Wait and use Task. WaitAny for the first one to come back.


2 Answers

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

:)

like image 104
Jon Skeet Avatar answered Oct 04 '22 14:10

Jon Skeet


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.

like image 29
Christian S Avatar answered Oct 04 '22 12:10

Christian S