gotmike gotmike - 2 months ago 40
C# Question

How to properly use FileSystemWatcher in C# -- Multiple Files and Getting "Lazy" on me

What I'm trying to do is watch a directory for new folders that are added.

Once a folder is added, I copy a standard directory structure from a different folder into this one and then use Open Office XML to do a Search and Replace on the contents of one of the Microsoft Word documents that is included in the source folders.

All is working great... EXCEPT:

1) If I copy more than one folder to the "watched" directory, one of them will get handled, none of the others will get processed. Also, after that, the app gets "stuck" and needs to be restarted to work again.

2) For some reason, it occasionally gets "lazy" on me and just quits working. Watching the console window it shows that it's at the

WaitForChanged
part of the code, but nothing happens. This seems to happen inconsistently.

Here is the FileSystemWatcher portion of the code (don't want to bore you with the OOXML and folder copying bits):

class soClass
{
private const string strDirectory = @"C:\[DIRECTORY-TO-WATCH\]";
private static FileSystemWatcher fw = new FileSystemWatcher(strDirectory);
private static void WatchIt()
{
// WHILE TRUE -- JUST MAKES IT RUN OVER AND OVER AGAIN...
while (true)
{

Console.WriteLine("Waiting on file/folder changes...");

// HANGS HERE ON THE 'REG
string strName = fw.WaitForChanged(WatcherChangeTypes.Created, -1).Name;

Console.WriteLine("File/Folder Added!");

Console.WriteLine("Starting over...");
Console.WriteLine("--------------------------------------------------------");

}

}
}


As always, any help is greatly appreciated.

UPDATE:

Here is the final code that worked, thanks to @openshac

class soClass
{

private const string strDirectory = @"C:\[DIRECTORY-TO-WATCH]";

private static void Main()
{
WatchIt();
}

public static void WatchIt()
{

FileSystemWatcher fw = new FileSystemWatcher();
fw.Path = strDirectory;
fw.Created += new FileSystemEventHandler(OnCreated);
Console.WriteLine("Waiting on file/folder changes...");

// BEGIN WATCHING
fw.EnableRaisingEvents = true;

// WAIT FOR USER TO QUIT THE PROGRAM
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}

private static void OnCreated(object sender, FileSystemEventArgs fileSystemEventArgs)
{

Console.WriteLine("File/Folder Added!");

string strName = fileSystemEventArgs.Name;

// DO STUFF HERE!!

Console.WriteLine("Starting over...");
//rwlock.ExitWriteLock();
Console.WriteLine("--------------------------------------------------------");

}
}


Also found some help here:
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx

Answer

From the documenation:

This method waits indefinitely until the first change occurs and then returns.

https://msdn.microsoft.com/en-us/library/67220zhk(v=vs.110).aspx

If you want to listen to multiple events try using the OnCreated event:

    var fw = new FileSystemWatcher();
    fw.EnableRaisingEvents = true;
    fw.Created += OnCreated;
}

private static void OnCreated(object sender, FileSystemEventArgs fileSystemEventArgs)
{
    var name = fileSystemEventArgs.Name;
}