我正在编写一些代码来观看(日志)文件。我使用Notepad ++来更新文件 我收听更改事件,有时文件被锁定,即使我的文件读数周围有lock语句 就像StreamReader或FileStream释放文件一样,但操作系统(带有dotnet4.5.1的win8)会再锁定一段时间?
我知道更改事件被调用twice的警告但是lock语句应该处理它。我想。到现在为止。
private static object _fileLock = new Object();
..
_watch.Changed += new FileSystemEventHandler(watch_Changed);
..
void watch_Changed(object sender, FileSystemEventArgs e)
{
lock (_fileLock)
{
using (var sr = new FileStream(_pathAndFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
// read in file...
sr.Close();
}
}
}
答案 0 :(得分:3)
你真的很困惑锁定的想法。 Changed事件处理程序中的 lock 语句是您用来阻止其他线程使用共享资源的一种锁。我们无法在您的代码段中看到此类资源。
锁定文件是一种完全不同的动物。 FileShare枚举是相关的,它说明了其他代码对文件的访问权限。将代码包含在另一个进程中, lock 关键字从未出现过这种情况。使用FileShare.ReadWrite,您在自己的代码中非常宽容。这允许任何其他进程读取和写入文件。您需要担心的是,当您在阅读文件时,当另一个进程可以写入文件时,您的代码是否仍能正常工作?换句话说,您在阅读时可以处理文件数据更改吗?这是非常罕见的,您必须了解其他进程正在使用此文件做什么。也非常难以测试。
这足以引入真正的问题。 FileSystemWatcher.Change事件被触发而另一个进程正在写入该文件。为了能够在事件处理程序中打开该文件,打开该文件的进程必须为您要求的访问权限提供共享权限。在您的情况下,它必须至少指定FileShare.Read,以便您具有FileAccess.Read访问权限。
永远不要指望永远如此。对于正在编写文件的程序员来说,一个非常合理的推理是“当我忙于编写文件时,其他任何人都无法永远正确读取此文件”。所以他指定了FileShare.None。 Kaboom在你的代码中,你无法打开它。
你无能为力,是其他程序员说你无法让它发挥作用。有很高的可能性,他完全正确。
您可以通过稍后阅读文件来处理此问题。在写完文件的过程完成之后。只需记住文件的路径,将其放在线程安全的队列中。现在您可以使用 lock 语句。使用计时器定期尝试再次打开文件。