Despite my large and growing number of Dispose-related blogs, I really don't like writing about Dispose. Or rather, I don't like that Dispose is in such a confusing state that it requires so much reading material. :) But here we are again. I'd like to start posting some of the common Dispose questions I get, in hopes that it will save time for others.
I got an email asking why StreamWriter's data isn't getting flushed to disk. In their scenario, the problem manifested as a partial file; i.e., the final block wasn't flushed to disk. But they also showed a smaller repro in which no data is flushed to disk.
using System; using System.IO; using System.Threading; public class StreamWriterWrapper : IDisposable { public StreamWriter writer; public static void Main(string[] args) { StreamWriterWrapper test = new StreamWriterWrapper(@"C:\temp\test.txt"); test.writer.WriteLine("some text"); test.writer.WriteLine("some more text"); } public StreamWriterWrapper(string filename) { writer = new StreamWriter(filename); } public void Dispose() { writer.Close(); } }
using System; using System.IO; using System.Threading;
public class StreamWriterWrapper : IDisposable { public StreamWriter writer;
public static void Main(string[] args) { StreamWriterWrapper test = new StreamWriterWrapper(@"C:\temp\test.txt"); test.writer.WriteLine("some text"); test.writer.WriteLine("some more text"); }
public StreamWriterWrapper(string filename) { writer = new StreamWriter(filename); }
public void Dispose() { writer.Close(); } }
The user's comment was: it looks like .NET isn't calling Dispose for us, even though we implemented IDisposable and provided a Dispose method, and this is why the data isn't getting flushed.
The user is completely right. And this is a key difference between Dispose and finalization. Dispose(void) doesn't get called for you; your code needs to explicitly call it. This is different than finalization, and since Brian has already written up a great description of this difference, I'll refer you to his blog for more details:
http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx