Guys,
Your argument has gone astray. The point is not in closing the handle - yes, operating system will always close all handles of the process when process is being shut down. However, OS didn't get the data written to the stream writer because those data are still in the writer's buffer. It has nothing to do with the OS.
So let's do some examples that demonstrate this.
First example:
You don't necessarily have to dispose the stream writer in order to have data written to disc. You just have to flush it:
StreamWriter logF = new StreamWriter(@"D:\tmp.txt");
string part = "01234567\r\n";
logF.Write(part);
logF.Flush();
This code alone will have data written to disc even before you close the process (e.g. enter the breakpoint after flush and open the file - you'll see its content there). However, it is bad practice not to dispose stream writer, because otherwise file on disc remains locked for writing quite indefinitely (until the writer is finalized by the GC).
Second example
You can set the stream writer's AutoFlush property to true. Then the writer will call flush on every call to Write method. This is quite bad behavior having on mind disc performance:
StreamWriter logF = new StreamWriter(@"D:\tmp.txt");
string part = "01234567\r\n";
logF.AutoFlush = true;
for (int i = 0; i < 1000; i++)
logF.Write(part);
This code will produce a file which is exactly 10,000 bytes in size.
Third example
If you omit AutoFlush=true line and do not flush manually and do not dispose the writer, then writer will flush data every time its internal buffer is full. In my test it occurs on every 1 kB, i.e. every 1024 bytes, and even then data will be visible in file only after the process is shut down regularly. That's the handle closing part you've been talking about - OS and disc themselves also have buffers and do not flush data to the medium more often then appreciated. But when OS closes the handle, it forces flush of all accompanying buffers.
StreamWriter logF = new StreamWriter(@"D:\tmp.txt");
string part = "01234567\r\n";
for (int i = 0; i < 250; i++)
logF.Write(part);
This piece of code in my test produces a file of 2048 bytes in length, and not 2500 as it has tried to do.
Fourth example
Another solution is to set up your own buffer size:
StreamWriter logF = new StreamWriter(@"D:\tmp.txt", false, Encoding.Default, 719);
string part = "01234567\r\n";
for (int i = 0; i < 250; i++)
logF.Write(part);
This code establishes stream writer with exactly 719 bytes of buffer space. Once the code is executed and process shut down regularly, the file will remain with 2157 bytes of data (instead of attempted 2500 bytes), which means that stream writer has flushed three times on its own.
Hope this has clarified the issue.
Edited by zoranh, 09 July 2010 - 06:20 AM.
Corrected typo in number