views:

1936

answers:

5

My asp.net application sending httpwebrequest to remote REST server and waiting for the response, and I found there are lots of same error message like this:

System.Net.WebException: The operation has timed-out.
at System.Net.HttpWebRequest.GetResponse()

Is that possible that after I catch this exception and close the underlying http connection directly? or I don't really have to do so since I already set keepalive to false?

Thanks.

Actually another questions is if the timeout exception always happened at System.Net.HttpWebRequest.GetResponse(), does that mean application is waiting for the response from remote server and could not get response until time out. what could be the possible reason, network connection not stable? remote server not response? any other possible reasons?

Here is the code:

System.Net.HttpWebResponse httpWebResponse = null;
System.IO.Stream stream  = null;
XmlTextReader xmlTextReader  = null;
try
{
    System.Net.HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(request);
    httpWebRequest.ReadWriteTimeout = 10000;
    httpWebRequest.Timeout = 10000;
    httpWebRequest.KeepAlive = false;
    httpWebRequest.Method = "GET";
    httpWebResponse = (System.Net.HttpWebResponse)httpWebRequest.GetResponse();
    stream = httpWebResponse.GetResponseStream();
    xmlTextReader = new  XmlTextReader(stream);
    xmlTextReader.Read();
    xmlDocument.Load(xmlTextReader);
    //Document processing code.
    //...
}
catch
{
    //Catch blcok with error handle
}
finally
{
    if (xmlTextReader != null)
        xmlTextReader.Close();
    if (httpWebResponse != null)
        httpWebResponse.Close();
    if (stream != null)
        stream.Close();
}
+2  A: 

The simple rule-of-thumb is that if it doesn't implement IDisposal then it doesn't need disposing of.

Dan Diplo
did not implement IDisposal, but I found there are many connections in CLOSE_WAIT condition, not sure what happened, worried about if my code did not handle the underlying connections properly.
machinegone
I think you have to trust the Framework designers on this one. Check out http://stackoverflow.com/questions/716436/is-there-a-correct-way-to-dispose-of-a-httpwebrequest for more info.
Dan Diplo
Dan, Thanks. seems there is really nothing more I can do.
machinegone
+1  A: 

Timeouts can happen due to two main factors:

1) The server is responding slowly. 2) The client is not disposing of the HttpWebResponse, in which case it runs out of outbound connections to use. Since, HTTP protocol limits clients to two connections per server.

Anyway, looking at your code, I see that you are closing the response in the finally block. In addition, I would make sure to close the ErrorResponse in the catch block as follows:

catch(WebException we)
{
    if (we.Status == WebExceptionStatus.ProtocolError)
    {
        ((HttpWebResponse)we.Response).Close();
    }
}

Back to the question at hand. It is very difficult to say what is going on without tracing. Use the instructions at the following link: http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html to enable tracing and look at the log. It might give you hints as to what is going on.

feroze
Thanks a lot for the help, I will add the code to close ErrorResponse in catch block. I will enable the trace and check for more information. Thanks!
machinegone
+1  A: 

Make sure to dispose as well as close.

Or use using blocks instead of try-finally:

using (var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse()) {
    using (var stream = httpWebResponse.GetResponseStream()) {
        using (var xmlTextReader = new XmlTextReader(stream)) {
            xmlDocument.Load(xmlTextReader);
        }
    }
}
Joe Chung
Thanks for the information.
machinegone
+1  A: 

One other thing you can do is call the Abort() method on an HTTPWebRequest that has resulted in an error, like so:

catch (WebException we)
{
    using (HttpWebResponse errorResp = we.Response as HttpWebResponse)
    {
    ...
    }
    request.Abort();
}
+1  A: 

Also you could increase the number of outbound connections in the machine.config:

<system.net>
  <connectionManagement>
     <add address="*" maxconnection="2" />
  </connectionManagement>
</system.net>

Change the maxconnection attr to something higher, see: http://www.williablog.net/williablog/post/2008/12/02/Increase-ASPNET-Scalability-Instantly.aspx

Obiwan