Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do we need to close the System.Net.WebRequest's ResponseStream?

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 ?

like image 854
Pacerier Avatar asked Sep 12 '11 10:09

Pacerier


People also ask

What is System Net WebRequest?

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.

What is the use of 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.

How do I reply to WebRequest?

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.


1 Answers

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.

like image 75
Jon Skeet Avatar answered Sep 21 '22 12:09

Jon Skeet