Search code examples
c#.nethttpwebrequestwebrequest

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?


Solution

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

    :)