在完成线程之前等待FileSystemWatcher事件触发

时间:2010-11-03 19:18:16

标签: c# multithreading filesystemwatcher

这有点令人费解,但我会尽力解释。

我正在使用FileSystemWatcher,其通知过滤器为

toFileWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName;

我有.Created方法和.Changed方法。

当.Created事件触发时,它会使用观察程序提供的文件名进行一些初步检查,检查文件是否已被查看,获取目标文件夹,并返回验证信息。

我遇到了一个问题,即验证位于.Created方法的末尾,它会在将文件复制到目标之前访问该文件进行一些验证。当我到达这一点时,如果文件很大并且仍然在从其源复制的过程中,则返回io“文件已在使用中”错误。

我想要做的是完成所有初步代码,然后我希望线程“挂起”,直到文件的.Changed方法触发,表明文件已完成,因为我只是将更改捕获到最后一次访问过滤器。

4 个答案:

答案 0 :(得分:2)

使用可以使用ManualResetEvent。 Created方法可以完成其工作,然后等待Created方法可以继续的Changed事件信号。

答案 1 :(得分:1)

这个问题很正常,通常在其他进程忙于写入文件时通常无法打开文件。你需要等待,你无法预测何时完成。将文件的路径添加到列表中并使用计时器清空该列表,定期重试该操作。仔细考虑逻辑,你正在使用线程,所以你需要用锁来保护列表。

答案 2 :(得分:1)

我会使用生产者 - 消费者模式设置一个单独的线程,该模式监视项目出现在队列中。这些项目将代表文件更改,并包含诸如文件路径和发生的更改类型之类的信息。您的FileSystemWatcher事件处理程序只会将项目发布到队列中,并让使用者线程出列并处理信息。这将从文件系统通知事件中解除所需的处理,从而更容易避免“文件在使用中”问题。

答案 3 :(得分:1)

请注意NotifyFilters.LastAccess并不意味着您将知道其他进程何时完成该文件。它只是意味着当文件的上次访问时间发生变化时会收到通知。

我通常会选择Brian Gideon的制作人 - 消费者模式。这也可以轻松过滤出Changed愉快地发出的(典型的)多个FileSystemWatcher事件。

(几乎)确定其他进程已完成该文件的唯一方法是尝试获取其上的独占锁定。但这并不总是足够的。我已经看到一个FTP服务器关闭并重新打开它写入的每个块的文件;-)

另请注意,FileSystemWatcher确实有一个内部缓冲区,它缓存从Windows获取的文件通知,但是如果发生很多事情,这个缓冲区可能会溢出。这也是创建生产者 - 消费者的原因。

我通常通过创建一个例程来修改它,该例程可以手动扫描被监视的目录,然后偶尔运行一次。是的,民意调查; - )

在启动应用程序时,使用此例程也很不错。文件可能在它关闭时到达了!