FileSystemWatcher的陷阱

我正在开发一个需要使用FileSystemWatcher类的C#程序,以便在创建新文件时通知它。 作为初始化的一部分,程序扫描目录,以便它可以处理其中已存在的任何文件。 这一切都很好。

但是,在与另一位开发人员的讨论中,我们开始质疑这是否始终有效。 是否存在FileSystemWatcher错过文件创建的条件? 如果是这样,这些条件是什么?

为了处理这种情况,我们只是在初始化过程中运行代码,定期扫描目录,但FileSystemWatcher丢失文件的可能性有多大?

FileSystemWatcher 通常不会遗漏文件。 然而:

  • 因为它基于ReadDirectoryChangesW ,它只检测文件目录条目的更改,而不是文件本身的更改。 对文件的大多数更改都将更新目录条目,但也有一些例外(请参阅此文章 )。
  • 文件更改通知的缓冲区大小有限; 如果你没有足够快地处理事件,缓冲区将溢出,导致你错过事件。 这就是为什么你不应该在事件处理程序中进行任何繁重的处理; 如果您无法足够快地处理事件,只需将它们添加到您在另一个线程上处理的队列中。

其他陷阱:

  • 通知不会立即到达; 实际更改和通知之间的延迟通常很短,但我已经看到它长到几秒钟。 对于大多数用例而言,这不是一个主要问题,但取决于您尝试做什么,这可能是一个问题。
  • Moved没有活动。 如果将文件从目录移动到另一个目录,则会收到两个通知: DeletedDeleted Created
  • 有时,根据卷配置,通知中的路径可以采用旧的8.3格式(例如,您可以获得SOMETH~1.TXT而不是Something.txt
  • 如果将现有的非空目录移动到监视目录中,则只会获得目录本身的通知,而不是其内容。 您需要手动检查内容。
  • 对于同一文件, Changed事件可能会多次发生; 你需要自己处理重复

FileSystemWatcher不应该遗漏任何文件,但是,如果您的文件处理很长,您应该对事件进行排队并在不同的线程中处理它们。

我有时间使用fs观察者,FSwatcher在创建文件时创建事件触发器的最大挑战(实际上没有最终大小),这意味着如果有人插入文件共享一个巨大的文件“演出”将被锁定直到创建者应用程序发布的文件,所以我可以在测试环境中看到完美,其中可以显示有限的文件和数据。 对于生产fswatcher结合后台工作者和计时器可以是解决方案,例如FSwatcher创建甚至应该将任务移交给后台工作者。 我仍然看到一些情况,我需要有一个小时计时器来移动剩余的文件,有一些奇怪的情况,当用户仍在几小时内使用文件。 我发现完美的解决方案使用FSwatcher以及multithreading和计时器。 我假设你想要一个Windows服务而不是基于表单或基于Web的应用程序。 对于文件更改事件,我不会使用此,如果任何应用程序在文件流中打开文件它将执行几个更改,但仍然锁定文件,所以你可以无所事事,也许你可以添加到列表,以便能够稍后处理它,但据我所知,在这种情况下,如果文件是在流中编辑的,它将继续向你发射事件。 所以我的建议使用创建的事件设置一些超时事件来检查真正的快速读取可用性,如5秒,如果这不是发生产生后台线程,甚至bg踏板仍然无法处理文件,有一个计时器,保持重试在所有文件中,在两种情况下都没有处理(如巨大的文件和服务终止,然后你的后台线程处理)。

总结FSwatcher引发事件,但这并不意味着文件可以访问并准备好进行处理,它只是监视文件系统并触发您订阅的事件。 事件正在触发,但是如果你没有足够快地处理它,你可能会错过下一个,所以如果你创建了很多文件,就像使用事件进行非常快速的操作,比如将它们添加到列表中,以及单独的威胁要做任务! 如果你在活动中花费太多时间,你可能会错过一些,所以抓住事件,立即切换任务并等待下一个:)