1

How can I write a logfile from a C# service so that it gets flushed to disk in a timely fashion?

Here's what I've tried. In logging code, I opened a file like this:

var file = return File.Open(name, FileMode.Append, 
                            FileAccess.Write, FileShare.Read);
var writer = new StreamWriter(file);

and wrote to it like this:

writer.WriteLine(msg);
writer.Flush();
file.Flush();

However the log was not flushed to disk in a timely fashion. So I tried adding a 5-second timer that does this:

[DllImport("kernel32.dll")]
static extern bool FlushFileBuffers(IntPtr hFile);

file.Flush();
var hdl = file.SafeFileHandle;
FlushFileBuffers(hdl.DangerousGetHandle());

This appears to work, but at infrequent intervals I get the following exception:

System.IO.IOException: The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.

at System.IO.FileStream.VerifyOSHandlePosition()

Is there a better way to force the flush?

Eric
  • 11,392
  • 13
  • 57
  • 100

1 Answers1

0

Per this answer, under .NET 4.0 it's enough to just call

file.Flush(true)

Messing around with the p/Invoke call is no longer required.

Community
  • 1
  • 1
Eric
  • 11,392
  • 13
  • 57
  • 100
  • 1
    MS bug report [here](http://connect.microsoft.com/VisualStudio/feedback/details/634385/filestream-flush-flushtodisk-true-call-does-not-flush-the-buffers-to-disk#details) says file.Flush(true) is broken, then fixed, but doesn't say what version or service pack it was fixed in! Sounds like bug was if internal .NET FileStream buffer is empty, the Flush(true) did nothing?? – jimvfr Nov 09 '12 at 02:34