I've have some code similar to this:
HttpWebRequest req;
HttpWebResponse response;
Stream receiveStream = null;
StreamReader readStream = null;
try
{
req = (HttpWebRequest)WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";
response = (HttpWebResponse)req.GetResponse();
receiveStream = response.GetResponseStream();
readStream = new StreamReader(receiveStream, Encoding.Default);
return readStream.ReadToEnd();
}
catch
{
return "Error";
}
finally
{
readStream = null;
receiveStream = null;
response = null;
req = null;
}
Should this code have readStream.Dispose() and responseStream.Dispose() instead of setting both to null?
Yes, StreamReader , StreamWriter , BinaryReader and BinaryWriter all close/dispose their underlying streams when you call Dispose on them. They don't dispose of the stream if the reader/writer is just garbage collected though - you should always dispose of the reader/writer, preferrably with a using statement.
You needn't call either Close or Dispose . MemoryStream doesn't hold any unmanaged resources, so the only resource to be reclaimed is memory. The memory will be reclaimed during garbage collection with the rest of the MemoryStream object when your code no longer references the MemoryStream .
To do it right, you just need to know that Dispose() calls Close() (a pretty intimate piece of implementation trivia). Further, in the Dispose(bool) cases, you need to ignore Dispose() and just write a Dispose(bool) implementation that makes sure to chain the base class method.
StreamWriter. Dispose() does close the underlying stream.
It's almost always a mistake to set local variables to null, unless you want to actually use that value later on. It doesn't force garbage collection any earlier - if you're not going to read from the variable later, the garbage collector can ignore the reference (when not in debug mode).
However, it's almost always correct to close streams - ideally in a using
statement for simplicity.
It's also almost always wrong to have a bare "catch" block like that. Do you really want to handle anything going wrong, including things like OutOfMemoryException
?
I would rewrite your code as:
HttpWebRequest req = (HttpWebRequest) WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";
using (WebResponse response = req.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(),
Encoding.Default))
{
return reader.ReadToEnd();
}
}
Now if something goes wrong, the exception will be propagated to the caller. You might want to catch a few specific exceptions, but it's generally not a good idea to represent errors using a value which could have been a valid "normal" response.
Finally, are you really sure you want Encoding.Default
? That's the default encoding of the local machine - you normally want the encoding indicated by the response itself.
It should have using
[which calls Dispose()
].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With