Introduction
If you've tried to use the FileSystemWatcher to wake up and process a newly created file in some directory, you have likely experienced what I did after coding the simple example found in this Microsoft Tutorial. When testing in either Debug or Release mode (outside the debugger), the Event Handler is invoked twice for a single file dropped in the target directory.
For my particular application, this wouldn't be fatal since I will need to scan the entire directory at "process" time and once the files are processed they are deleted. In other words, a second call to a method that reads in a list of existing filenames and then dispatches a worker method to load a database with the data contained in those files is an innocuous operation.
Nonetheless, in my testing, I was confounded as to why the double callbacks occurred. After searching the Web, I found little in the way of a fix. I did find several other folks that found the double callback behavior problematic for a variety of reasons.
The workaround is premised on my best guess that the Framework is notified by the OS when the file handle is created/opened and then again when it is closed (file writing is completed). Given that, I added a FileInfo inquiry to the event handler which asks the OS if the file which has been reported as CREATED is, in fact, in the file system. Seems that on the first callback, this test consistently fails.
The highlights from my C# proof-of-concept project are below with the entire project in the zip download.
static void Main(string[] args)
{
watcher = new FileSystemWatcher();
watcher.Path = mailbox;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press Enter to quit\r\n");
Console.ReadLine();
}
public static void OnChanged(object source, FileSystemEventArgs e)
{
watcher.EnableRaisingEvents = false;
FileInfo objFileInfo = new FileInfo(e.FullPath);
if (!objFileInfo.Exists) return;
ProcessAllFiles(e.FullPath);
}
History
- 20th June, 2006: Initial post