Tuesday, October 17, 2006 #

Readers, Writers and IDisposable

You know what Readers and Writers are... Wrappers around Streams used to write or read data.
Usually, you make things like this:

        using (Stream stream = new MemoryStream())

        using (BinaryWriter writer = new BinaryWriter(stream))

        {

            writer.Write(10);

            writer.Write(20);

        }

You create your stream and your writer, use it and dispose both. But what if you mustn't dispose the stream?

public void Method()

    {

        using (Stream stream = new MemoryStream())

        {

            WriteToStream(stream);

            stream.Position = 0;

            // .. Read stream

        }

    }

 

    private void WriteToStream(Stream stream)

    {

        using (BinaryWriter writer = new BinaryWriter(stream))

        {

            writer.Write(10);

            writer.Write(20);

        }        // !! Dispose the writer and the underlying stream!

    }

The implicit call to Dispose on the writer at the end of the using block will dispose the writer and the underlying stream... Then you cannot read the stream anymore.

But since the writer is IDisposable, shouldn't I call Dispose on it ? And - more important - won't it dispose the stream at random time when the finalizer is called?

The response is No, and No.

Actually, the Readers and Writers are IDisposable so that you can manage the underlying stream lifetime without having to keep a reference on both objects. If you manually manage your stream lifetime, you don't have to dispose your reader or writer.

And what about the finalizer? It's never safe to use references to other managed objects in the finalizer since they can have been finalized before. Finalizers only release the unmanaged resources. So the writer won't dispose the stream when finalized. The writers and readers often don't directly reference unmanaged resources, and they don't even need a finalizer.

Here is the good way to write code above:

    private void WriteToStream(Stream stream)

    {

        BinaryWriter writer = new BinaryWriter(stream);

        writer.Write(10);

        writer.Write(20);

        // Just let the stream live

    }

Skup

posted @ 6:19 PM | Feedback (1)