שתף באמצעות


Will FileSystemWatcher process multiple files at once?

Question

Monday, June 1, 2009 9:56 PM

I have a Windows service that is watching a folder for files that will be placed there.  (Created in Visual Studio 2005.)  The files each represent a transaction, and the transactions have to be kept in order.  As I process each file (transaction), I want to forward it to someone else.  (The someone else wants them kept in order.) 

It looks like I can't paste multiple files into a folder simultaneously and still be sure that they will be processed in the order of the original date and time they were created.  Nor can I be sure that they would be read in name order. (FileSystemWatcher would grab them in any old order it chose.)  So I think I will have to move the files into the folder one at a time, in the proper sequence.  But I'm wondering if I could get into a "racing" situation. 

When FileSystemWatcher detects a file in a folder, it creates a new thread for your event handler to operate on.  If it detects a second file while still processing the first file, would it then create yet another thread?  If that is the case, then if File1.xml takes longer to process than File2.xml, it seems like File2.xml might finish first, resulting in my transactions getting out of order.

In my own experiments, I have not seen evidence that multiple files are really processed simultaneously.  I write messages to a log file as I process each transaction, and I never see messages from File1.xml's processing intermingled with File2.xml's messages.  This seems to be true even when I paste both files into the folder simultaneously.  But maybe I have just been lucky.

My hope is that it only keeps one event-handling thread going at a time, and queues up the events as they come, processing them on that single thread.  Otherwise, I'll have to do something to ensure they are kept in order.

Does anyone know the answer to this?

All replies (9)

Tuesday, June 2, 2009 9:07 PM ✅Answered | 2 votes

You should use some sort of structure to process the files instead of processing inside the event handler, just add the file to the pipeline inside the event. Spin off a separate thread which would keep monitoring and whenever a file is added, just processes it. If this post is useful, mark it as answer.


Tuesday, June 2, 2009 11:22 AM

Files are never be loaded on a disk at the same time.

Your event handling will always done one by one, they are fired and handled in the sequence they are fired.
As long as your program is single threaded, you even cannot do more events in one time. Therefore is threading created.

However, as you do this in a thread or something like that, then I would create a Queue and Enque and Deque that then in the main program (don't forget to synclock those enqueing and dequeing.

Cor

Dear Cor,
I am currently doing same thing in my program. I am not using any threading. I am only handling files creation in a folder. When i save a file to the folder (for example using notepad), my event handler gets called twice and i see two forms on screen (although this form is displayed modal which means the execution should be halted!). Any wise thoughts?

@Micheal,
Yes the FileSystemWatcher creates a new thread for every event call. You would realize that not only the order of the files is a problem but when you are looking to deal with files created, filewatcher would launch your event handler twice or may be more times for EACH file. This is because when programs save files, first they create the empty file (causing the event) and then copy the content and finish the file (causing the event again). This is a very annoying known problem with filesystemwatcher.
I use these statements at the start and end of my event handler to avoid the event fired multiple times

filesystemwatcher1.enableraisingevents = False

then at the end
filesystemwatcher1.enableraisingevents = True
If this post is useful, mark it as answer.


Tuesday, June 2, 2009 2:30 PM

Let me rephrase what you said, to verify my understanding.  Even though I may attempt to drop the files into the watched folder simultaneously, my file-watching service will always process them one at a time.  I will never have two files being processed at the same time.  In effect, the FileSystemWatcher has its own queue of fired events, and sends them to an event handler one at a time.  True? 

Then why do I need the Queue processing you describe?  Are you saying that I only need that if I intentionally create another thread, other than the one created by FileSystemWatcher?

Even if the events are handled in sequence, can I really be sure that Event 1 will have finished processing before Event 2 begins its work?


Tuesday, June 2, 2009 2:42 PM

Thanks, CodeCruiser.  I had been copying the files into the folder, which fires only one event, but the file-creation scenario you describe could be a headache for me at some point.

I wonder if turning EnableRaisingEvents off and on in your handler is really a safe way of doing things, though.  It seems like a file could arrive in the folder at the instant that you turn off the file watching, resulting in missed files.  If your file processing is quick, you might be lucky most of the time, and never hit this "dead zone" in your listening.  But in my case, even one missing transaction would be a disaster.

It seems like you would need to keep some kind of list of files currently being processed, and remove the file from the list when you are done with it.  Successive events would have to check this list so as not to process the file twice.  Maybe that's what Cor is getting at with his Queue suggestion.

I wonder if the first file-creation event would then be premature in attempting to process the file - if the file doesn't yet have content, you wouldn't want to process it until the second event.  True?


Tuesday, June 2, 2009 2:44 PM | 1 vote

Yes. The filesystemwatcher would execute your event for each file but it wont be that it launches event for second file only when event for first has finished. It launches the event handler for each file almost simultaneously. The reason i disable event raising during the event execution is to avoid multiple events launched for same file as i described above. You may not want to do that depending on your app. You can experiment with that by writing the time upto milliseconds into a listbox with the path of the file to see the sequence and timing of the event launching. If this post is useful, mark it as answer.


Tuesday, June 2, 2009 3:57 PM

Okay, thanks.  I'll leave this thread open for a little bit to see if Cor or anyone else has additional comments or suggestions.


Tuesday, June 2, 2009 4:11 PM

Okay, thanks.  I'll leave this thread open for a little bit to see if Cor or anyone else has additional comments or suggestions.

Michael,

As you simply use a filewatcher in a single thread for a local drive then in my idea everything is said.

Just look at the events which you want to handle and then there are no extras to know 

Success

Cor


Tuesday, June 2, 2009 4:16 PM

Michael,
Is there anything you are still unsure of? If this post is useful, mark it as answer.


Tuesday, June 2, 2009 4:25 PM

I gather from your comments, CodeCruiser, that I probably do need to worry about simultaneous transactions racing each other and getting out of order.  But I'm not clear on whether Cor agrees with you.  If he does agree, then maybe I should look into his Queue suggestion, or something similar, to keep my transactions in order.