FileSystemWatcher does not fire after sometime

I have the following code that i use to monitor a directory for text files, the directory gets new files twice a day, the code works fine for sometime but after that it stops firing OnCreated event…

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public static void Run()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"c:\users\documents\";

    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;

    watcher.Filter = "*.txt";

    // Add event handlers.
    watcher.Created += new FileSystemEventHandler(OnCreated);

    // Begin watching.
    watcher.EnableRaisingEvents = true;

    // Wait for the user to quit the program.
    Console.WriteLine("Press \'q\' to quit the sample.");
    while(Console.Read()!='q');
}

private static void OnCreated(object source, FileSystemEventArgs e)
{
   Console.WriteLine("File: " +  e.FullPath + " " + e.ChangeType);
}

Cannot figure out the issue.

Also, I would like to know a foolproof alternative to this (if any), since I am not finding this reliable..

  • Note that FileSystemWatcher has a bit of a reputation for being unreliable (though I’m not sure if this is a problem with FileSystemWatcher‘s implementation or with how it’s being used). See stackoverflow.com/questions/239988/… for suggestions on how others have dealt with the problem.

    – 

  • Also, my understanding is that FileSystemWatcher uses the system’s ReadDirectoryChangesW API. It might help to read this article by Jim Beveridge on the details of that API: qualapps.blogspot.com/2010/05/…

    – 

Because after the Run method has completed, watcher is eligible for garbage collection.
This means that after some time watcher will be collected and obviously will stop raising events.

To solve, keep a reference of the watcher in the outer scope:

private static FileSystemWatcher watcher;

public static void Run()
{
    watcher = new FileSystemWatcher();
    ...
}

The Problem with this was that the reference to the FILESYSTEMWATCHER was being collected by the GC and hence after sometime the FILEWATCHER had a null reference leading to events not getting raised.

Solution :-

private static FileSystemWatcher watcher;
public static void Run()
{
watcher = new FileSystemWatcher();
...
GC.KeepAlive(watcher);  
}

Just keeping a reference of the watcher in the outer scope as suggested did not solve the problem. I had be explicitly specify that GC should not collect the FileWatcher object.

Assuming your watcher isn’t going out of scope, there’s you can check for any errors that occur such as running out of the watchers internal buffer…

watcher.Error += Watcher_Error;
...
private void Watcher_Error(object sender, ErrorEventArgs e)
{
Debug.WriteLine("Watcher_Error: " + e.GetException().Message);
}

Leave a Comment