FileSystemWatcher skips Created-events



我有一个FileSystemWatcher,可以检查多个目录是否创建了任何文件。

((System.ComponentModel.ISupportInitialize)(FileMonitor)).BeginInit();
FileMonitor.EnableRaisingEvents = true;
FileMonitor.Created += new FileSystemEventHandler(FileMonitor_Created);
FileMonitor.Path = Path.ToString();
FileMonitor.IncludeSubdirectories = true;
FileMonitor.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Attributes;
((System.ComponentModel.ISupportInitialize)(FileMonitor)).EndInit();

由于某种原因,在运行应用程序时并不总是触发 FileMonitor_Created 事件,即使它应该触发。感觉很随机...

但是,如果我在 FileMonitor_Created 方法上放置断点,它就可以完美地工作:如果设置了断点,则每次都应触发事件。

我试过为文件监视器设置InterBufferSize,但没有效果。

更新

我将Changed事件添加到文件监视器,并为其提供了与Created事件相同的处理程序。不知何故,它现在可以工作了,尽管文件实际上是创建的,而不是更改的。

我仍然很好奇为什么它在设置断点时总是以"旧方式"工作。

您做了多少更改?

Windows 操作系统会通知您的组件文件更改 在文件系统观察器创建的缓冲区中。如果有很多 在短时间内发生变化,缓冲区可能会溢出。这会导致 组件会丢失对目录中更改的跟踪,它只会 提供一揽子通知。增加缓冲区的大小 InternalBufferSize 属性很昂贵,因为它来自 无法换出到磁盘的非分页内存,因此请保留 缓冲区小而大,不会错过任何文件更改事件。 若要避免缓冲区溢出,请使用通知筛选器和 包括子目录属性,以便您可以过滤掉不需要的更改 通知。

摘自 MSDN

如果你有一个断点,它可以工作,但如果你没有,它就不工作了?

您确定事件处理程序中没有某些内容吗?就像发生了异常,使程序"感觉"好像它什么都不做?您可以在处理程序中发布代码吗?

将业务逻辑与FileMonitor_Created事件分开。 在这种情况下,您应该存储事件参数并返回。 例如,将事件参数存储在队列中,然后异步处理这些事件。

FileMonitor.Created 在创建文件且未替换为具有相同创建日期时间的上一个文件时触发。

场景 1)复制粘贴并右键单击相同的abc.txt输入文件夹中的文件,而不对文件创建日期或文件内容进行任何更改- - 文件观察器无法识别该文件。

场景 2)复制粘贴并右键单击输入文件夹中具有新创建日期的相同文件 文件观察器识别文件

因此,创建的事件适用于第二种情况,这可能不是您的情况,但对于我的第一个视图来说,它看起来是隐藏的行为。

引发事件时,文件处理可能需要一些时间。在此期间,可能会创建另一个文件,事件处理程序将不会处理第二个文件,因为它仍在处理第一个文件。因此,第二个文件被FileSystemWatcher丢失。

解决方案是将文件检测表单文件处理分成两个线程,然后通过队列进行连接。它是生产者-消费者队列。

文件检测应尽可能短。它应该只检测一个文件,将其文件名排队到文件处理线程可以处理的队列中,然后关闭,以便可以检测到另一个文件。文件处理线程可以将文件名取消排队,并花费尽可能多的时间来处理它。

我用本文中的代码详细解释了这一点:文件系统观察器跳过一些事件

最新更新