将日志刷新到磁盘,VerifyOSHandlePosition 中出现异常

发布于 2025-01-03 15:59:51 字数 913 浏览 1 评论 0原文

如何从 C# 服务写入日志文件以便及时将其刷新到磁盘?

这是我尝试过的。在日志记录代码中,我打开了一个像这样的文件:

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

并像这样写入它:

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

但是日志没有及时刷新到磁盘。因此,我尝试添加一个 5 秒计时器来执行此操作:

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

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

这似乎有效,但偶尔会出现以下异常:

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()

有更好的方法强制刷新吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离旧人 2025-01-10 15:59:51

根据 这个答案,在 .NET 4.0 下,只需调用 Messing 就足够了,

file.Flush(true)

不再需要 p/Invoke 调用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文