Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do i need to Dispose Stream when i Pass it to IDisposable class?

I wrote a piece of code. I want to make sure that I am Disposing an Object in right way.

I have a Disposable Class like this Which is used to read some data from unmanaged resource.

class MyFileReader : IDisposable
{
    private readonly FileStream _stream;

    public MyFileReader(FileStream stream)
    {
        _stream = stream;
    }

    public void Dispose()
    {
        _stream.Dispose();
    }
}

Currently in my program I Dispose objects like this.

        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (MyFileReader reader = new MyFileReader(stream))
            {
                //...
            }
        }

This seems ok to me. later I have noticed That Classes are passed by reference so maybe if I dispose one of them there is no need to dispose the other one.

My question is Can i Do Something like this?

        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            MyFileReader reader = new MyFileReader(stream);
            // Remove IDisposable from MyFileReader and stream will close after using.
        }

Or this one?

        FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
        // stream will close after using.
        using (MyFileReader reader = new MyFileReader(stream))
        {
            //...
        }
like image 810
M.kazem Akhgary Avatar asked Jul 07 '15 04:07

M.kazem Akhgary


People also ask

What happens if you dont Dispose IDisposable?

IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.

Does StreamReader Dispose stream?

Yes, StreamReader , StreamWriter , BinaryReader and BinaryWriter all close/dispose their underlying streams when you call Dispose on them.

Do I need to Dispose FileStream?

In the specific case of a FileStream , you don't need to dispose it to close the file, you only need to use the Close method. You should however dispose of the FileStream object anyway, as it has a finalizer.

How do you Dispose of IDisposable?

If you don't use using , then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().


2 Answers

Yes, you can write code like that.

But, no, you should not do that.

Your class looks like on of XxxxReader classes that by convention own the stream they read from. As result your MyFileReader class is expected to dispose the inner stream. You also normally expected to dispose each and every disposable object when you know that such object's lifetime is over.

Note that sometimes it lead to multiple Dispose calls on some objects (which should be expected by implementations of IDisposable). While it may sometimes lead to Code Analysis warning it is better than missing Dispose calls if one routinely tries to "optimize" number of calls to Dispose by skipping some.

Alternative approach is to expose method that reads content which by convention is not expected to take ownership of stream/reader like:

 using(stream....)
 {
   var result = MyFileReader.ReadFrom(stream);
 }
like image 100
Alexei Levenkov Avatar answered Sep 23 '22 15:09

Alexei Levenkov


If MyFileReader is accessing some unmanaged resource and you need the Disponse method to be called explicitly after this code block, then you have to stick with your current implementation.

In the second implementation, the Dispose method will not be called for the MyFileReader object. (until you probably call it in the destructor which you don't know when that would be called)

If you do not like the nested using, then you can probably go with the second alternative and in the Dispose() method implementation of MyFileReader class, explicitly dispose the Stream. If this stream is only use by MyFileReader, then this is a good practice to have MyFileReader manage its lifecycle and dispose it.

like image 28
n00b Avatar answered Sep 25 '22 15:09

n00b