0

I have a method like so

private bool VerbMethod(string httpVerb, string methodName, string url, string command, string guid, out HttpWebResponse response)

I use this like this

  HttpWebResponse response;
  if (VerbMethod("POST", "TheMethod", "http://theurl.com", "parameter1=a", theGuid, out response))
  {
    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
    {
      string responseString = sr.ReadToEnd();
    }

It returns a bool to specify if the method went well, and the response is set in an out parameter to get the data.

I sometimes get a timeout, and then subsequent requests also times out. I saw this SO WebRequest.GetResponse locks up?

It recommonds the using keyword. The problem is, with the above method signature I'm not sure how to do it.

  • Should I manually call dispose in a finally?
  • Is there some way to still use using with the out parameter?
  • Rewrite the method, so it doesn't expose the HttpWebResponse?
Community
  • 1
  • 1
CracyD
  • 368
  • 4
  • 16

6 Answers6

6

It returns a bool to specify if the method went well

That's your problem. Don't use a Boolean success value: throw an exception if something goes wrong. (Or rather, let the exception bubble up.)

Just change your method to return the response.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

If you want to use using (without exceptions), just swap the bool and the response:

private HttpWebResponse VerbMethod(string httpVerb, string methodName, string url, string command, string guid, out bool canExecute);


bool canExecute = false;

using(HttpWebResponse response = VerbMethod("POST", "TheMethod", "http://theurl.com", "parameter1=a", theGuid, out canExecute))
{
  if (canExecute)
  {
    ..
  }
}
Matten
  • 17,365
  • 2
  • 42
  • 64
0

Assigne default value to out parameter immediately in the beginning of the function, and continue use using as you already use it.

Tigran
  • 61,654
  • 8
  • 86
  • 123
0

you can also use

    HttpWebResponse response;
    if (VerbMethod("POST", "TheMethod", "http://theurl.com", "parameter1=a", theGuid, out response))
    {
        using (response)
        {
            using (System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
            {
                string responseString = sr.ReadToEnd();
            }
        }
    }
Waqar
  • 2,511
  • 18
  • 15
0

You can add another using for response:

HttpWebResponse response; 
if (VerbMethod("POST", "TheMethod", "http://theurl.com", "parameter1=a", theGuid,
   out response)) 
{ 
  using(response)
  {
    using (StreamReader sr = new StreamReader(response.GetResponseStream())) 
    { 
      string responseString = sr.ReadToEnd(); 
    } 
  }
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0

You can do this:

private bool VerbMethod(string httpVerb, string methodName, string url, 
  string command, string guid, out HttpWebResponse response) {}

HttpWebResponse response = null;

if(VerbMethod(httpVerb, methodName, url, command, guid, out response) {
  using(response)
  {
    using (StreamReader sr = new StreamReader(response.GetResponseStream())) {
    }
  }
}

The using statement doesn't require that the expression(s) within it is/are new objects or method returns - any expression will do.

However - generally a request doesn't fire until you call GetResponseStream() so I can't see that your bool return is actually doing anything other than confirming that an object has been created - and there's no point in unit testing the runtime(!). Therefore the best thing is to make the method return the response and put that in the using instead. I can see from the other answers that I'm not alone in this.

That same argument, however, could be used to justify just making the change I list above.

Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160