0

我正在编写一些代码来查看(日志)文件。我使用 Notepad++ 来更新文件。
我收听更改事件,有时文件被锁定,即使我在文件读取周围有一个锁定语句。
就像StreamReaderFileStream释放文件但操作系统(带有dotnet4.5.1的win8)保持锁定更多时间

我知道 Changed 事件被调用两次的警告,但 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();
        }
    }
}
4

1 回答 1

3

您严重混淆了锁定的想法。Changed 事件处理程序中的lock语句是您用来防止另一个线程使用共享资源的锁。我们看不到您的代码段中使用了这样的资源。

文件上的锁是一种完全不同的动物。FileShare 枚举是相关的,它说明其他代码对文件有什么样的访问权限。将代码包含在另一个进程中, lock关键字永远不会出现这种情况。您对自己的代码非常宽容,使用 FileShare.ReadWrite。这允许任何其他进程读取和写入文件。您需要担心的是,当另一个进程可以在您读取文件时写入文件时,您的代码是否仍然可以正常工作?换句话说,您是否可以在读取文件时处理文件数据的变化。这非常罕见,您必须非常了解其他进程正在使用此文件做什么。也极难测试。

对真正问题的介绍就足够了。FileSystemWatcher.Change 事件另一个进程正在写入文件时触发。为了能够在您的事件处理程序中打开该文件,打开该文件的进程必须为您请求的访问类型授予共享权限。在您的情况下,它必须至少具有指定的 FileShare.Read 以便您具有 FileAccess.Read 访问权限。

永远不要指望总是如此。对于正在编写文件的程序员来说,一个非常理智的理由是“当我忙于编写文件时,其他任何人都无法正确读取该文件” 所以他指定了 FileShare.None。Kaboom 在您的代码中,您无法打开它。

您对此无能为力,是其他程序员说您无法使其工作。很有可能他是完全正确的。

您可以稍后通过阅读该文件来处理这个问题。在写入文件的过程完成后。只需记住文件的路径,将其放在线程安全队列中。现在您可以使用该lock语句了。使用计时器定期尝试再次打开文件。

于 2013-07-03T21:14:17.400 回答