2014-01-08 85 views
4

我就需要使用FileSystemWatcher类,以便创建新文件时它会通知C#程序的工作。作为初始化的一部分,程序扫描目录,以便它可以处理其中已有的任何文件。这一切工作正常。FileSystemWatcher的陷阱

然而,与其他开发者的讨论,我们开始质疑这是否就没有问题。有没有条件下FileSystemWatcher将错过创建文件?如果是这样,这些条件是什么?

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

+0

这个以前的问题/答案应该给你一个好的开始:http:/ /stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes。简而言之,FileSystemWatcher底层的Win32缓冲区可能会溢出 – Kevin

+1

[.NETFramwork 4中的FileSystemWatcher的可靠程度如何?](http://stackoverflow.com/questions/7191380/how-reliable-is-the-filesystemwatcher-in -netframwork-4) – Yuck

回答

11

FileSystemWatcher将不会通常未中的文件。但是:

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

其他陷阱:

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

感谢您的详细回复。我们已经知道多个更改事件和移动陷阱。我已阅读过有关今天早些时候移动非空目录的问题。我不知道目录条目与文件本身的问题。幸运的是,我只对添加新文件感兴趣,而不是对现有文件的更改。再次感谢! –

2

FileSystemWatcher是不应该错过任何文件,但是,如果你的文件处理很长,你应该队列中的事件,并在不同的线程对待他们。

0

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

概要FSwatcher引发事件,但并不意味着文件可以被访问和准备处理,它只是监视文件系统并激发你订阅的事件。事件触发,但如果你没有足够快地处理它,你可能会错过下一个事件,所以使用事件进行非常快速的动作,如果你创建了很多文件,比如将它们添加到列表中,任务!如果你在一个事件中花费太多时间,你可能会错过一些,所以赶上事件,立即交接任务,并等待下一个:)