Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a FileSystemWatcher thread run forever?

I need to have a FileSystemWatcher run in an infinite loop to monitor a file for changes, but this file will only change every few days, and maybe only once a week. In the MSDN sample of a FileSystemWatcher, there is a loop while the user doesn't enter q at the console:

while(Console.Read()!='q');

I don't want this to be constantly available so it isn't accidentally killed - it has to run with no user intervention in an infinite loop. Do I have to change the loop to

while (true);

so the thread doesn't exit? This alone isn't ideal as it will peg the CPU - adding a Thread.Sleep call would eliminate the CPU load, and in this case, could be a long sleep as the file very rarely changes. Is this the best way to go? How should I make sure this thread remains alive so the FileSystemWatcher can act when a file changes? This is running on a Windows server(with .NET framework version 2.0), so making it a Windows service would be possible if necessary.

like image 921
Tai Squared Avatar asked Mar 18 '09 21:03

Tai Squared


2 Answers

If this is running on a server, a service seems like a good bet.

If you want something a little more interactive, I have a small application that lives in my system tray to show me when something happens in our Issues folder. It uses the Application.Run() method to keep itself going without the need for a loop, i.e.

class MainEntryClass
{
    static void Main(string[] args)
    {
        FolderAlerter fa = new FolderAlerter(); 
        Application.Run();
    }
}

Then I set up my FileSystemWatcher in FolderAlerter.

like image 66
aehiilrs Avatar answered Oct 13 '22 16:10

aehiilrs


Basically, FileSystemWatcher is using some of the built-in hooks to subscribe to changes and just gets the OS to call your delegates when a change occurs. So all you have to do is stop your main thread from exiting, it doesn't have to actually do anything; By the time you get to that line, the main part of your program is over, it has done what it needed to do.

A simple way of doing what you want is to make this change to the sample from MSDN;

//while (Console.Read() != 'q') ;
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

This will put your main thread to sleep forever, but will still allow the delegates to fire and respond to changes in the directory. Note that it will keep running through multiple changes (just like the MSDN sample).

Note that the "while" in the MSDN sample doesn't really do much; You could replace that line with just "Console.Read()", which would then make any key quit the application. It's just a line to stop the main thread from exiting so that it is still around when the event notifications come in.

However, using the Sleep(Timeout.Infinite) leaves your app in a state where it cannot be easily stopped by a user, other than by killing the app. If you are writing this as a console app, why not stick with the "press Q to quit"? If you decide to write it as a service instead it will probably be OK, as long as you handle the shutdown/restart events etc.

like image 37
flytzen Avatar answered Oct 13 '22 18:10

flytzen