简体   繁体   English

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

[英]After FileSystemWatcher fires - Thread Pool or Dedicated thread?

I am about to implement the archetypal FileSystemWatcher solution. 我即将实现原型FileSystemWatcher解决方案。 I have a directory to monitor for file creations, and the task of sucking up created files and inserting the into a DB. 我有一个目录来监控文件创建,以及吸收创建的文件并将其插入数据库的任务。 Roughly this will involve reading and processing 6 or 7, 80 char text files that appear at a rate of 150mS in bursts that occur every couple of seconds, and rarely a 2MB binary file will also have to be processed. 大致这将涉及读取和处理6或7,80个字符文本文件,每隔几秒发生一次150毫秒的爆发,很少还需要处理2MB二进制文件。 This will most likely be a 24/7 process. 这很可能是一个24/7的过程。

From what I have read about the FileSystemWatcher object it is better to enqueue its events in one thread and then dequeue/process them in another thread. 从我读到的有关FileSystemWatcher对象的内容来看,最好将其事件排入一个线程,然后在另一个线程中将它们出列/处理。 The quandary I have right now is what would be the better creation mechanism of the thread that does the processing. 我现在遇到的困境是进行处理的线程的更好的创建机制。 The choices I can see are: 我能看到的选择是:

  1. Each time I get a FSW event I manually create a new thread (yeah I know .. stupid architecture, but I had to say it). 每次我收到FSW事件时,我都会手动创建一个新线程(是的,我知道......愚蠢的架构,但我必须说出来)。

  2. Throw the processing at the CLR thread pool whenever I get an FSW event 每当我收到FSW事件时,都会在CLR线程池中抛出处理

  3. On start up, create a dedicated second thread for the processing and use a producer/consumer model to handle the work. 在启动时,为处理创建专用的第二个线程,并使用生产者/消费者模型来处理工作。 The main thread enqueues the request and the second thread dequeues it and performs the work. 主线程将请求排队,第二个线程将其排队并执行工作。

I am tending towards the third method as the preferred one as I know the work thread will always be required - and also probably more so because I have no feel for the thread pool. 我倾向于将第三种方法作为首选方法,因为我知道工作线程将始终是必需的 - 而且可能更多因为我对线程池没有感觉。

The third option is the most logical. 第三种选择是最合乎逻辑的。

In regards to FSW missing some file events, I implemented this: 1) FSW Object which fires on FileCreate 2) tmrFileCheck, ticks = 5000 (5 seconds) - Calls tmrFileChec_Tick 关于FSW丢失一些文件事件,我实现了这个:1)在FileCreate上触发的FSW对象2)tmrFileCheck,ticks = 5000(5秒) - 调用tmrFileChec_Tick

When the FileCreate event occurs, if (tmrFileCheck.Enabled == false) then tmrFileCheck.Start() 当FileCreate事件发生时,如果(tmrFileCheck.Enabled == false)则tmrFileCheck.Start()

This way, after 10 seconds tmrFileCheck_Tick fires which a) tmrFileCheck.Stop() b) CheckForStragglerFiles 这样,10秒后tmrFileCheck_Tick会触发a)tmrFileCheck.Stop()b)CheckForStragglerFiles

Of tests I've run, this works effectively where there are a < 100 files created per minute. 在我运行的测试中,这在每分钟创建<100个文件的情况下有效。

A variant is to merely have a timer tick ever NN seconds and sweep the directory(ies) for straggler files. 一个变体是只有一个计时器滴答NN秒并扫描目录(ies)为straggler文件。

Another variant is to hire me to press F5 to refresh the window and call you when there are straggler files; 另一个变种是雇用我按F5刷新窗口,并在存在straggler文件时给你打电话; just a suggestion. 只是一个建议。 :-P :-P

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

Just be aware that FileSystemWatcher may miss events, there's no guarantee it will deliver all specific events that have transpired. 请注意,FileSystemWatcher可能会错过事件,但无法保证它会提供已发生的所有特定事件。 Your design of keeping the work done by the thread receiving events to a minimum, should reduce the chances of that happening, but it is still a possibility, given the finite event buffer size (tops out at 64KB). 您将接收事件的线程完成的工作保持在最低限度的设计应该减少发生这种情况的可能性,但考虑到有限事件缓冲区大小(最高为64KB),它仍然是可能的。

I would highly recommend developing a battery of torture tests if you decide to use FileSystemWatcher. 如果您决定使用FileSystemWatcher,我强烈建议您开发一系列酷刑测试。

In our testing, we encountered issues with network locations, that changing the InternalBufferSize did not fix, yet when we encountered this scenario, we did not receive Error event notifications either. 在我们的测试中,我们遇到网络位置问题,更改InternalBufferSize没有修复,但是当我们遇到这种情况时,我们也没有收到错误事件通知。

Thus, we developed our own polling mechanism for doing so, using Directory.GetFiles , followed by comparing the state of the returned files with the previously polled state, ensuring we always had an accurate delta. 因此,我们使用Directory.GetFiles开发了我们自己的轮询机制,然后将返回文件的状态与先前轮询的状态进行比较,确保我们始终具有准确的delta。

Of course, this comes at a substantial cost in performance, which may not be good enough for you. 当然,这会带来相当大的性能成本,这对您来说可能不够好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM