FileSystemWatcher触发后 - 线程池还是专用线程?

时间:2010-02-22 00:55:41

标签: c# multithreading threadpool filesystemwatcher

我即将实现原型FileSystemWatcher解决方案。我有一个目录来监控文件创建,以及吸收创建的文件并将其插入数据库的任务。大致这将涉及读取和处理6或7,80个字符文本文件,每隔几秒发生一次150毫秒的爆发,很少还需要处理2MB二进制文件。这很可能是一个24/7的过程。

从我读过的关于FileSystemWatcher对象的内容来看,最好将其事件排入一个线程,然后在另一个线程中将它们出列/处理。我现在遇到的困境是进行处理的线程的更好的创建机制。我能看到的选择是:

  1. 每次我收到FSW事件时,我都会手动创建一个新线程(是的,我知道......愚蠢的架构,但我不得不这么说)。

  2. 每当我收到FSW事件时,都会在CLR线程池中抛出处理

  3. 启动时,为处理创建专用的第二个线程,并使用生产者/消费者模型来处理工作。主线程将请求排队,第二个线程将其排队并执行工作。

  4. 我倾向于将第三种方法作为首选方法,因为我知道工作线程将始终是必需的 - 而且可能更多因为我对线程池没有感觉。

3 个答案:

答案 0 :(得分:3)

如果您知道将始终需要第二个线程,并且您知道您将永远不需要多个工作线程,那么选项三是好的够了。

答案 1 :(得分:3)

第三种选择是最合乎逻辑的。

关于FSW丢失一些文件事件,我实现了这个: 1)在FileCreate上触发的FSW对象 2)tmrFileCheck,ticks = 5000(5秒)     - 调用tmrFileChec_Tick

当FileCreate事件发生时,如果(tmrFileCheck.Enabled == false)则tmrFileCheck.Start()

这样,10秒后tmrFileCheck_Tick会触发哪一个 a)tmrFileCheck.Stop() b)CheckForStragglerFiles

在我运行的测试中,这在有<的地方有效。每分钟创建100个文件。

一个变体是只需要一个NN秒的计时器滴答,并扫描目录(ies)以寻找落后者文件。

另一种变体是聘请我按F5刷新窗口,并在存在straggler文件时给你打电话;只是一个建议。 :-P

答案 2 :(得分:2)

请注意,FileSystemWatcher可能会错过事件,但无法保证它会传递所有已发生的特定事件。您将接收事件的线程完成的工作保持在最低限度的设计应该减少发生这种情况的可能性,但考虑到有限事件缓冲区大小(最高为64KB),它仍然是可能的。

如果您决定使用FileSystemWatcher,我强烈建议您开发一系列酷刑测试。

在我们的测试中,我们遇到了网络位置问题,更改了InternalBufferSize没有修复,但是当我们遇到这种情况时,我们也没有收到错误事件通知。

因此,我们使用Directory.GetFiles开发了自己的轮询机制,然后将返回文件的状态与先前轮询的状态进行比较,确保我们始终具有准确的delta。

当然,这会带来相当大的性能成本,对您来说可能不够好。