FileSystemWatcher generates duplicate events - How to workaround
I had to use the FileSystemWatcher class these days and I found out that it raises multiple duplicate events. If you are not familiar with FileSystemWatcher class, this class allows you to watch a particular folder and receive notifications/events every time there is change happening in that folder. You can subcribe to all sorts of events: file created, file changed, file renamed, file accessed, directory created, directory renamed, directory accessed, etc.
The problem is that multiple duplicate events are being raised. For instance, if I copy a file over an existing file, instead of raising one file changed event, the FileSystemWatcher object will raise 5 !!! such file change events that are identical. If you are creating a file, the FileSystemWatcher class will raise a file created event and at least a file changed event.
I think that some of these issues are caused by the Win32 APIs and they are normal, others (like the file createad and file changed events when creating a file) are probably caused by applications. Many applications will first create an empty file and then they will update the file with the file content hence the file created, file changed events being raised when creating a new document.
This can be worked around by queueing the events (let's say over a 1 second period) and then remove any duplicates. And this is what I did. I implemented my own version of FileSystemWatcher class (named DelayedFileSystemWatcher) that mimics MOST of the FileSystemWatcher behavior and it removes duplicate events.
DelayedFileSystemWatcher class will delay processing of any events that are being raised. All events that are raised (except error events) by the inner FileSystemWatcher object will be queued to a collection. The ElapsedEventHandler method will be invoked automatically (through a System.Timer.Timer event) every 1 second. This method will analyze all events in the queue. The first time an event is found, it will be marked as "Delayed" and it won't be processed. The next time the method is executed, the already "Delayed" events will be raised but first all events that are duplicate of "Delayed" events will be removed. An event in the queue will either be delayed (processing postponed for next timer event), raised (it's already delayed and it's the first event of his kind), or deleted (delayed or not but there was an event in front of it that was similar/duplicate).So this class mimics FileSystemWatcher but it removes duplicate events that show up within 2 timer events. A second event is duplicate of a first event if both events are of the same type and have all properties equal or if the second event is a an update/changed event, first event is a create event and both events refer to the same file.
See code file attached. DISCLAIMER: Use this code at your own risk. No support is provided and this code has NOT been tested.
[Last file update - February 09, 2006]