Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpWebRequest times out on second call

Why does the following code Timeout the second (and subsequent) time it is run?

The code hangs at:

using (Stream objStream = request.GetResponse().GetResponseStream()) 

and then causes a WebException saying that the request has timed out.

I have tried this with a WebRequest and HttpWebRequest

Edit: It seems the code is falling over in request.GetResponse()

Edit: This post suggests it may be a GC issue --> http://www.vbforums.com/showthread.php?t=610043 - as per this post the issue is mitigated if Fiddler is open in the background.

The server is there and available for requests.

    private string GetQLMResponse(string URL)     {         HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;         request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);         request.KeepAlive = false;         request.Timeout = 5000;         request.Proxy = null;          // Read stream         string responseString = String.Empty;         try         {             using (var response = request.GetResponse())             {                 using (Stream objStream = response.GetResponseStream())                 {                     using (StreamReader objReader = new StreamReader(objStream))                     {                         responseString = objReader.ReadToEnd();                         objReader.Close();                     }                     objStream.Flush();                     objStream.Close();                 }                 response.Close();             }         }         catch (WebException ex)         {             throw new LicenseServerUnavailableException();         }         finally         {             request.Abort();             request = null;             GC.Collect();         }         return responseString;     } 

Thrown WebException is:

{"The operation has timed out"} [System.Net.WebException]: {"The operation has timed out"} Data: {System.Collections.ListDictionaryInternal} HelpLink: null InnerException: null Message: "The operation has timed out" Source: "System" StackTrace: " at System.Net.HttpWebRequest.GetResponse()\r\n at IQX.Licensing.License.GetQLMResponse(String URL) in C:\Users\jd\SVN\jd\Products\Development\JAD.Licensing\JAD.Licensing\License.cs:line 373" TargetSite: {System.Net.WebResponse GetResponse()}


Update: OK So the following code now works. The servicePoint was setting the timeout to be near 4 minutes. Changing ServicePoint.ConnectionLeaseTimeout on the request object means that the request is now destroyed after 5000ms. Thanks to all for your help and also to these 2 pages:

  1. http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
  2. http://msdn.microsoft.com/en-us/library/6hszazfz(v=VS.80).aspx

    private string GetQLMResponse(string URL) {     HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;     request.Credentials = new NetworkCredential(Settings.Default.LicenseUser, Settings.Default.LicensePassword);     request.KeepAlive = false;     request.Timeout = 5000;     request.Proxy = null;      request.ServicePoint.ConnectionLeaseTimeout = 5000;     request.ServicePoint.MaxIdleTime = 5000;      // Read stream     string responseString = String.Empty;     try     {         using (WebResponse response = request.GetResponse())         {             using (Stream objStream = response.GetResponseStream())             {                 using (StreamReader objReader = new StreamReader(objStream))                 {                     responseString = objReader.ReadToEnd();                     objReader.Close();                 }                 objStream.Flush();                 objStream.Close();             }             response.Close();         }     }     catch (WebException ex)     {         throw new LicenseServerUnavailableException();     }     finally     {         request.Abort();     }     return responseString; } 
like image 775
Darbio Avatar asked Apr 29 '11 01:04

Darbio


People also ask

What is the default timeout for HttpWebRequest?

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

How do I set HttpWebRequest timeout?

Quick snippet of code: HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest. Create(url); webReq. Timeout = 5000; HttpWebResponse response = (HttpWebResponse)webReq.

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.


1 Answers

On the heels of the previous answers, I wanted to add a couple more things. By default HttpWebRequest allows only 2 connections to the same host (this is HTTP 1.1 "niceness"),

Yes, it can be overriden, no I won't tell you how in this question, you have to ask another one :) I think you ought to look at this post.

I think that you are still not quite disposing of all your resources connected with the HttpWebRequest, so the connection pooling comes into play and that's the problem. I wouldn't try to fight the 2 connections per server rule, unless you really have to.

As one of the posters above noted, Fiddler is doing you a bit of a disservice in this case.

I'd add a nice finally {} clause after your catch and make sure that as the above post notes, all streams are flushed, closed and references to the request object are set to null.

Please let us know if this helps.

like image 196
dawebber Avatar answered Oct 04 '22 07:10

dawebber