FileSystemWatcher跳过Created-events

时间:2012-10-25 14:33:05

标签: c# file-monitoring

如果有任何文件被创建,我有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方法中放置一个断点,它就可以完美地工作:如果设置了断点,则事件每次都会触发。

我已尝试为FileMonitor设置InterBufferSize,但这没有效果。

更新

我将Changed事件添加到Filemonitor并为其提供了与Created事件相同的处理程序。不知怎的,它现​​在有效,虽然文件实际上是创建的,但没有改变。

我仍然很好奇为什么它总是有效的'旧的方式'设置断点时。

5 个答案:

答案 0 :(得分:4)

你做了多少改变?

  

Windows操作系统会通知组件文件更改   在FileSystemWatcher创建的缓冲区中。如果有很多   在短时间内发生变化,缓冲区可能会溢出。这导致了   组件忘记跟踪目录中的更改,它只会   提供全面通知。增加缓冲区的大小   InternalBufferSize属性很昂贵,因为它来自   非分页内存,无法换出磁盘,所以保持   缓冲区虽小但足够大,不会错过任何文件更改事件。   要避免缓冲区溢出,请使用NotifyFilter和   IncludeSubdirectories属性,以便您可以过滤掉不需要的更改   通知。

取自MSDN

答案 1 :(得分:0)

如果你的断点有效,但如果你没有,那不是吗?

您确定事件处理程序中没有内容吗?就像有一个异常发生,让程序'感觉'就像没有做任何事情一样?你可以在处理程序中发布代码吗?

答案 2 :(得分:0)

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

答案 3 :(得分:0)

FileMonitor.Created在创建文件时触发,而不是用具有相同创建日期时间的上一个文件替换。

场景1)将粘贴复制到输入文件夹中的相同abc.txt文件,而不更改文件创建日期或文件内容 - 文件观察程序无法识别文件。

场景2)使用新创建的日期复制粘贴并将输入文件夹中的同一文件复制到右侧文件监视器识别文件

所以创建的事件适用于第二个场景,它可能不是你的情况,但看起来是我第一个视图的隐藏行为。

答案 4 :(得分:0)

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

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

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

我使用本文中的代码详细解释了这一点:FileSystemWatcher skips some events