Click here to Skip to main content
15,918,742 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My problem initially was to ensure that an instance of filesystemwatcher could recover from lost of network in a remote directory monitoring, or if de directory its was monitoring were to deleted and created again.

After a while searching the web I came up with this:

C#
class watcher
{

    static string _path;
    static string _mask;

    static FileSystemWatcher m_Watcher;

    public watcher(string path, string mask)
    {
        m_Watcher = new FileSystemWatcher();
        _path = path;
        _mask = mask;
    }

    public static void start()
    {
        m_Watcher.Filter = _mask;
        m_Watcher.Path = _path;


        m_Watcher.NotifyFilter = NotifyFilters.FileName;

        m_Watcher.IncludeSubdirectories = false;

        m_Watcher.Created += new FileSystemEventHandler(OnCreated);

        m_Watcher.Error += new ErrorEventHandler(OnError);

        m_Watcher.EnableRaisingEvents = true;


    }

    static void OnCreated(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("OnCreated " + e.FullPath);
    }

    static void OnError(object sender, ErrorEventArgs e)
    {

        if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
        {
            Console.WriteLine("Error: File System Watcher internal buffer overflow at " + DateTime.Now);
        }
        else
        {
            Console.WriteLine("Error: Watched directory " + _path + " not accessible at " + DateTime.Now + Environment.NewLine + e.GetException().Message + Environment.NewLine);
            NotAccessibleError(m_Watcher);
        }

    }


    static void NotAccessibleError(FileSystemWatcher m_Watcher)
    {
        int iMaxAttempts = 120;
        int iTimeOut = 5000;
        int i = 0;

        while ((!Directory.Exists(m_Watcher.Path) || m_Watcher.EnableRaisingEvents == false) && i < iMaxAttempts)
        {
            i += 1;
            try
            {
                m_Watcher.EnableRaisingEvents = false;

                if (!Directory.Exists(m_Watcher.Path))
                {
                    Console.WriteLine("Directory Inaccesible " + m_Watcher.Path + " at " + DateTime.Now.ToString("HH:mm:ss"));
                    System.Threading.Thread.Sleep(iTimeOut);
                }
                if (Directory.Exists(m_Watcher.Path))
                {


                    m_Watcher.Dispose();
                    m_Watcher = null;

                    m_Watcher = new FileSystemWatcher();

                      m_Watcher.Filter = _mask;
                        m_Watcher.Path = _path;


                        m_Watcher.NotifyFilter = NotifyFilters.FileName;

                        m_Watcher.IncludeSubdirectories = false;

                        m_Watcher.Created += new FileSystemEventHandler(OnCreated);

                        m_Watcher.Error += new ErrorEventHandler(OnError);

                        m_Watcher.EnableRaisingEvents = true;

                    Console.WriteLine("Restart RaisingEvents Watcher for " + _path + " at " + DateTime.Now.ToString("HH:mm:ss"));
                }
            }
            catch (Exception error)
            {
                Console.WriteLine("Error trying Restart Service " + error.StackTrace + " at " + DateTime.Now.ToString("HH:mm:ss"));
                m_Watcher.EnableRaisingEvents = false;
                System.Threading.Thread.Sleep(iTimeOut);
            }
        }
    }

}


And the code that calls this, as example:

C#
watcher watcher;

watcher = new watcher(@"C:\WORK\TESTING\01", "*.*");
watcher.start();
Console.WriteLine(@"starting Watcher for : C:\WORK\TESTING\01");

watcher = new watcher(@"C:\WORK\TESTING\02", "*.*");
watcher.start();
Console.WriteLine(@"starting Watcher for : C:\WORK\TESTING\02");

watcher = new watcher(@"T:\UTILS\TESTING\01", "*.*");
watcher.start();
Console.WriteLine(@"starting Watcher for : T:\UTILS\TESTING\01");

watcher = new watcher(@"T:\UTILS\TESTING\02", "*.*");
watcher.start();
Console.WriteLine(@"starting Watcher for : T:\UTILS\TESTING\02");

while (true)
{
    Thread.Sleep(5000);
}


If I only use one obj its works fine and recovers ok, but if I instance more than one obj of the class when he get an error it:

Assumes that there where 2 (for example) watcher that lost network but the information that I can see is only for the latest one that I have instanced.
So when the automatically recovers it creates 2 new watchers for the second directory.

It seems that the error is being thrown by the 2 obj’s but only the latest one is being stored and used by booth.

Any ideas for what I’m doing wrong?

Thanks in advance.
Posted
Updated 7-Aug-14 3:23am
v4

1 solution


You repeat the start code in NotAccessibleError. I believe that a simple rewrite of start would improve your code. The following is an example. Here m_Watcher has been replaced by file_watcher. Also, file_watcher is expected to be initialized to null in the class variable declarations.


C#
// ***************************************************** start

public static void start ( )
    {

    if ( file_watcher != null )
        {
        file_watcher.Created -= OnCreated;
        file_watcher.Error -= OnError;

        file_watcher.Dispose ( );
        file_watcher = null;
        }

    file_watcher = new FileSystemWatcher ( )
        {
        EnableRaisingEvents = true,
        Filter = Filter,
        IncludeSubdirectories = false,
        NotifyFilter = NotifyFilters.FileName,
        Path = Path
        };

    file_watcher.Created +=
        new FileSystemEventHandler ( OnCreated );
    file_watcher.Error +=
        new ErrorEventHandler ( OnError );
    }


You may be having problems by not deleting event handlers before adding new ones. In the revised start, that is repaired by removing the event handlers if file_watcher is not null.



By implementing this revision, all that needs be done is to invoke start ( ) appropriately in NotAccessibleError.



I changed watcher to FileWatcher. For the revised start to work, the FileWatcher constructor should not instantiate a new FileSystemWatcher. The following code is the revised class constants, class variables, and class constructor.


C#
// ********************************************* class FileWatcher

public class FileWatcher
    {

    // ******************************************* class constants

    const int MAXIMUM_ATTEMPTS = 120;
    const int TIMEOUT = 5000;

    // ******************************************* class variables

    static FileSystemWatcher    file_watcher = null;
    static string               filter = String.Empty;
    static string               path = String.Empty;

    // *********************************************** FileWatcher

    public FileWatcher ( string _path,
                         string _filter )
        {

        path = _path;
        filter = _filter;
        }


Hope that helps.

 
Share this answer
 
Comments
João Silva 11-Aug-14 13:16pm    
thank's a lot, going to test this ... not deleting event handlers must be the problem.
gggustafson 11-Aug-14 15:22pm    
I'm not sure that is the answer but its worth trying. If it works please rate my solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900