like numbers

[SOLVED] FileSystemWatcher problem

Wednesday, September 18th, 2013, 18:53 by Martin Andersson. Posted in Cloud, Coding |

Share on Facebook
Share on LinkedIn
Post on Twitter


FileSystemWatcher problemThe FileSys­temWatcher .NET class lis­tens to the file sys­tem and it is catch­ing any changes and noti­fi­ca­tions in it. When direc­to­ries, or files in direc­to­ries, are changed, events are raised.

When a file is cre­ated, the FileSys­temWatcher class will nor­mally be noti­fied twice. How­ever, up to 4 or more “events” can be fired depend­ing on which soft­ware is used to save the file. This can be dif­fi­cult to han­dle because the fired events caused by the same file will run in par­al­lel. For exam­ple, if the events started are mod­i­fy­ing the file cre­ated, only one will be able to open it. It then often hap­pens that a run-time error occurs in one of the other events. The rea­son is that they are try­ing to do exactly the same thing with the same file. Again. Some oper­a­tions just can’t be done more than once, like delet­ing a file.

Previous FileSystemWatcher solutions

There are plenty of post­ings on the Inter­net regard­ing the prob­lems with FileSys­temWatcher. The dou­ble or mul­ti­ple event prob­lem from file cre­ation is an issue. Actu­ally, I think it got worse with faster com­put­ers. They can han­dle events more and more in a truly par­al­lel fash­ion using mul­ti­ple proces­sors. But, even after try­ing all kinds of FileSys­temWatcher tricks and tips, copy­ing and past­ing from the inter­net, I still could not get a good behav­ior on some com­put­ers. Fur­ther­more, I thought that many of the solu­tions sug­gested (using try-catch, using global Boolean vari­ables to “lock out” or using polling instead), were not good.

The new solution

After giv­ing up the copy­ing and past­ing from the Inter­net, I started to think what should be done using my own brains, instead of copy­ing and past­ing.

The idea I came up with was that the par­al­lelism should be removed. Instead, the FileSys­temWatcher events should be put in a queue and be taken care of one by one. Inter­est­ingly, this can be eas­ily done using so called MONITORS. Actu­ally, I had had hap­pily for­got­ten about mon­i­tors, it’s a long time since I stud­ied, but when search­ing for sem­a­phores (which I hap­pened to remem­ber) I found out that mon­i­tors are more sim­ple and will solve the prob­lem very eas­ily.

Dim lock­This As New Object
Pri­vate Sub OnChange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
Syn­cLock lock­This
If File.Exists(e.FullPath) Then
Get­DataAnd­Delete(e.FullPath)
End If
End Syn­cLock
End Sub

Comments

First we declare a vari­able point­ing to type “Object”. When the event is fired, this object locked as soon as the first event is started. Any other event try­ing to access it (or even try­ing to lock it) will have to wait at that point in the code until the object is unlocked. As soon as it is released, the next event in line will then hold the object and pro­ceed. The other ones in the queue have to wait. In visual basic this is called Syn­cLock which may actu­ally be a bet­ter name than Mon­i­tor.

In this case, the test­ing con­di­tion was just to see if the file existed becuase in “Get­DataAnd­Delete”, the file will be deleted. There­fore, you may need more advanced con­di­tions to see if it is the same file­name com­ing again (within a short period of time).

Hope you like it!



Post a Comment