0

What is the benefit from a user's point of view for closing a stream?

When running this code, it doesn't make visible difference to the user, whether you comment out response.Close(); or not.

Can anyone give me an example where not closing a stream/file handle etc would cause a noticeable problem to the user?

    WebRequest request = WebRequest.Create("http://www.microsoft.com");
    WebResponse response = request.GetResponse();
    StreamReader responseStream = new StreamReader(response.GetResponseStream());
    string responseText = responseStream.ReadToEnd();
    Console.WriteLine(responseText); // Displays the HTML of the website
    response.Close();

EDIT: Everyone is saying stuff like "it's good to dispose/close a stream so you release unmanaged resources". But can anyone provide me with an example showing how this can create a noticeable difference to the end user?

David Klempfner
  • 8,700
  • 20
  • 73
  • 153
  • 1
    Suppose you had a database connection in your system. Suppose that many users were using this system creating lots of connections. If you didn't close the connections (which are unmanaged resources) you may get into a situation where there are too many connections and new connections would be rejected – TJF Feb 26 '14 at 13:32
  • Is there anything missing in the given answers? If so, what are you missing? – Max Feb 26 '14 at 21:11
  • I haven't had a chance to read the answers, when I do I'll select one as the best answer. – David Klempfner Feb 27 '14 at 22:17

3 Answers3

4

It is important to close/dispose all streams, when done using them.
Best way to do this is by using a using statement:

using(StreamReader responseStream = new StreamReader(response.GetResponseStream())
{
    //streamreader will be disposed automatically,
    //when done executing within brackets.
}

If the stream(s) isn't/aren't properly closed/disposed, it will cause a memory leak. Resources used by the stream, will be released when closing/disposing the stream.

Everyone is saying stuff like "it's good to dispose/close a stream so you release unmanaged resources". But can anyone provide me with an example showing how this can create a noticeable difference to the end user?

Try following code in your application:

private void LoopUndisposedStream()
{
    for(int i = 0; i < 5000000; i++)
    {
       CreateUndisposedStream();
    }
}

private void CreateUndisposedStream()
{
    WebRequest request = WebRequest.Create("http://www.microsoft.com");
    WebResponse response = request.GetResponse();
    StreamReader responseStream = new StreamReader(response.GetResponseStream());
    string responseText = responseStream.ReadToEnd();
    Console.WriteLine(responseText); // Displays the HTML of the website
}

Above code is what, you should absolutely NEVER do. But since you're asking for an example, showing the performance problems, when not disposing every stream. Here it is.

Max
  • 12,622
  • 16
  • 73
  • 101
  • What about the finalizer? (which isn't a reason not to `Dispose()` it) – C.Evenhuis Feb 26 '14 at 12:41
  • @C.Evenhuis sorry, I don't understand your question. Why shouldn't we dispose all disposable objects? – Max Feb 26 '14 at 12:45
  • what is so bad about a memory leak? – David Klempfner Feb 26 '14 at 12:57
  • 1
    Your application will run slower, since memory is being held by a stream that isn't closed and isn't used anymore. So for example when your code runs 20 times, you will have 20 unclosed streams, that will reserve memory at the pc, where the application is running at. Short answer: Your application will consume more and more memory every time it opens a stream without closing. The user will have less and less memory for other applications. – Max Feb 26 '14 at 12:59
  • @MaxMommersteeg yes you _should_ dispose any `IDisposable`, but the finalizer _should_ ensure that as soon as an object is no longer referenced, its resources are freed. There will only be a true memory leak if the finalizer doesn't clean up properly. – C.Evenhuis Feb 26 '14 at 14:03
  • @C.Evenhuis Ah, you mean the GarbageCollector? The `.Dispose()` method calls: `GC.SuppressFinalize(this);`, for freeing up resources. – Max Feb 26 '14 at 14:07
  • @MaxMommersteeg actually it calls `GC.SuppressFinalize(this)` to indicate that the finalizer need not run during garbage collection because `Dispose()` already freed up resources. A finalizer looks like this: `~MyClass() { }`. See http://stackoverflow.com/a/1076976/292411 – C.Evenhuis Feb 26 '14 at 14:34
4

By closing a stream you release the resources bound up with it, although those resources can vary depending on the type of stream you use, with some having greater impact that others.

Take FileStream for example. While the stream is open it has an open handle on the file. If you do not close it the handle will not be released until the object is garbage collected at some unspecified point in the future.

Now, depending on how you opened that file you might run into issues, take for example this:

FileStream file = new FileStream("example.dat",FileMode.Open,FileAccess.Read,FileShare.None);

This gets an exclusive lock on the file which won't be released. This means any other calls to open the file and read will fail.

So it's always better, especially when dealing with classes that interface with unmanaged resources to release as soon as you're done.

One of the easiest ways of doing this is using the using construct, for example:

using (FileStream file = new FileStream("example.dat",FileMode.Open,FileAccess.Read,FileShare.None)) {
    // Do something useful
}

You can use using with any class that implements IDisposable and it will ensure that once outside of the scope of the statement Dispose is called and any resources are released.

Lloyd
  • 29,197
  • 4
  • 84
  • 98
1

By closing a Stream you release resources, in addition you make some objects that you no longer need eligible for GargabeCollector so it reduces memory usage etc.

Max
  • 12,622
  • 16
  • 73
  • 101
w.b
  • 11,026
  • 5
  • 30
  • 49