.net 为什么FileSystemWatcher.Changed和StreamReader或FileStream会锁定文件,即使我锁定了(…){…}它?

.net 为什么FileSystemWatcher.Changed和StreamReader或FileStream会锁定文件,即使我锁定了(…){…}它?,.net,filesystemwatcher,.net,Filesystemwatcher,我正在写一些代码来查看(日志)文件。我使用记事本++更新文件。 我收听更改事件,有时文件被锁定,即使我在文件读取时有一条语句。 它类似于或释放文件,但操作系统(带dotnet4.5.1的win8)会将锁保留一段时间吗 我知道调用已更改事件的警告,但是lock语句应该注意这一点。我想。直到现在 private static object _fileLock = new Object(); .. _watch.Changed += new FileSystemEventHandler(watch_C

我正在写一些代码来查看(日志)文件。我使用记事本++更新文件。
我收听更改事件,有时文件被锁定,即使我在文件读取时有一条语句。
它类似于或释放文件,但操作系统(带dotnet4.5.1的win8)会将锁保留一段时间吗

我知道调用已更改事件的警告,但是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();
        }
    }
}

您严重混淆了锁定的概念。更改的事件处理程序中的lock语句是用来防止其他线程使用共享资源的锁。我们无法在您的代码片段中看到这样的资源

文件上的锁是一种完全不同的动物。FileShare枚举是相关的,它表示其他代码对该文件的访问方式。在另一个进程中包含代码,lock关键字永远不会出现这种情况。使用FileShare.ReadWrite,您对自己的代码非常宽容。它允许任何其他进程读取和写入文件。这是您必须担心的一点,当另一个进程可以在您读取文件时写入文件时,您的代码是否仍能正常工作?换句话说,您能否在读取文件时处理文件数据的更改。这是非常罕见的,您必须知道很多关于其他进程对该文件所做的操作。也非常难测试

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

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

对此你无能为力,是另一个程序员说你不能让它工作。很有可能他在这一点上是完全正确的


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

您严重混淆了锁定的概念。更改的事件处理程序中的lock语句是用来防止其他线程使用共享资源的锁。我们无法在您的代码片段中看到这样的资源

文件上的锁是一种完全不同的动物。FileShare枚举是相关的,它表示其他代码对该文件的访问方式。在另一个进程中包含代码,lock关键字永远不会出现这种情况。使用FileShare.ReadWrite,您对自己的代码非常宽容。它允许任何其他进程读取和写入文件。这是您必须担心的一点,当另一个进程可以在您读取文件时写入文件时,您的代码是否仍能正常工作?换句话说,您能否在读取文件时处理文件数据的更改。这是非常罕见的,您必须知道很多关于其他进程对该文件所做的操作。也非常难测试

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

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

对此你无能为力,是另一个程序员说你不能让它工作。很有可能他在这一点上是完全正确的


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

lock语句与文件无关。C#不包含任何特定于文件的功能。那太专业化了。lock语句与文件无关。C#不包含任何特定于文件的功能。那太专业化了。