I was wondering will I end up having any unclosed streams from this code:
Public Function [Get](ByVal url As String) As String
Using reader = New System.IO.StreamReader(System.Net.WebRequest.Create(url).GetResponse.GetResponseStream)
Return reader.ReadToEnd
End Using
End Function
What about this:
Public Function Get2(ByVal url As String) As String
Using stream = System.Net.WebRequest.Create(url).GetResponse.GetResponseStream
Using reader = New System.IO.StreamReader(stream)
Return reader.ReadToEnd
End Using
End Using
End Function
Basically, do we need to close the System.Net.WebRequest
's ResponseStream
?
WebRequest is an abstract class that models the request side of transactions used for accessing data from the Internet. Classes that derive from WebRequest are required to override the following members of the WebRequest class in a protocol-specific manner: System. Net. WebRequest.
WebRequest descendants are typically registered to handle a specific protocol, such as HTTP or FTP, but can be registered to handle a request to a specific server or path on a server. The WebRequest class throws a WebException when errors occur while accessing an Internet resource.
The GetResponse method sends a request to an Internet resource and returns a WebResponse instance. If the request has already been initiated by a call to GetRequestStream, the GetResponse method completes the request and returns any response. The GetResponse method provides synchronous access to the WebResponse.
You either need to close the response stream or you need to close the response. Note that closing a StreamReader
wrapping a Stream
will close the stream anyway, so the first version should be okay. (Note that I'm deeming "dispose with a Using statement" to be semantically equal to "close in a finally block" - there's no benefit in explicitly calling Close
instead of just disposing of the stream or response.)
I believe that closing the stream is good enough - that you don't need to close the response as well - and indeed that's what MSDN states, but personally I'd do so for clarity:
Public Function [Get](ByVal url As String) As String
Using response = WebRequest.Create(url).GetResponse
Using reader = New System.IO.StreamReader(response.GetResponseStream)
Return reader.ReadToEnd
End Using
End Using
End Function
(There's a theoretical benefit here that it will close the response if GetResponse
returns successfully but either GetResponseStream
or the StreamReader
constructor throws an exception. I don't expect that to have any practical implications.)
If you don't close anything, you could very easily run into timeouts in future requests to the same host - the "open" response will essentially hog the connection to that host, and by default there's a limit of two open connections per host. This is a very common cause of timeouts - there are lots of SO questions where folks are getting timeouts due to not closing anything.
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