Search code examples
c#streamdispose

Is "not disposing StreamWriter" may cause memoryLeak in that case?


I have method that as follows

public int TranslateOOV(string word, Stream logStream)
{
StreamWriter writer = new StreamWriter(logStream);

//Do some logging
//dont close the writer and leave the caller close the stream
}

I do not close the StreamWriter as the caller should close the inner stream, does this cause memoryleak?


Solution

  • Just for fun I cracked open the decompiler to look at what Dispose does on a StreamWriter (thinking perhaps the underlying stream is the only resource needed disposed). Here is what came out:

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (this.stream != null)
            {
                if (disposing || (this.Closable || this.stream as __ConsoleStream))
                {
                    this.Flush(true, true);
                    if (this.mdaHelper != null)
                    {
                        GC.SuppressFinalize(this.mdaHelper);
                    }
                }
            }
        }
        finally
        {
            if (this.Closable)
            {
                if (this.stream != null)
                {
                    if (disposing)
                    {
                        this.stream.Close();
                    }
                    this.stream = null;
                    this.byteBuffer = null;
                    this.charBuffer = null;
                    this.encoding = null;
                    this.encoder = null;
                    this.charLen = 0;
                    base.Dispose(disposing);
                }
            }
        }
    }
    

    A bit wordy, but I think what this is telling us is that disposing the stream takes care of the only Disposable resource used by the StreamWriter. The byteBuffer and charBuffer fields are arrays, encoding and encoder are not disposable, and the base Dispose is virtual, so the Stream is the only thing that will cause problems if it is not cleaned up.

    I think this also makes it clear that if you are wanting to log the contents of the stream, and leave it in a usable state afterwards, then you most defiantly do not want to dispose your StreamWriter, because that will dispose the Stream (Close calls Dispose(true)). You also want to make sure you reset the position of the Stream since you will no doubt change it by reading the contents. Of course that also means that you probably want to check the CanSeek property on the Stream and make sure that once you read the contents you will be able to return the position to where it was before.