控制来自filesystemwatcher obj的多个实例的错误 [英] Control Errors from several instances of a filesystemwatcher obj

查看:81
本文介绍了控制来自filesystemwatcher obj的多个实例的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最初的问题是确保filesystemwatcher的实例可以从远程目录监视中的网络丢失中恢复,或者如果它监视的de目录被删除并再次创建。



经过一段时间搜索网络后,我想出了这个:



  class 观察者
{

静态 string _path;
static string _mask;

static FileSystemWatcher m_Watcher;

public watcher( string 路径, 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 ;


}

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

静态 void OnError( object sender,ErrorEventArgs e)
{

if (e.GetException()。 GetType()== typeof (InternalBufferOverflowException))
{
Console.WriteLine( 错误:文件系统观察器内部缓冲区溢出 + DateTime.Now);
}
else
{
Console.WriteLine( 错误:监视目录 + _path + not not not not可在 + DateTime.Now + Environment.NewLine + e.GetException()。Message + Environment.NewLine);
NotAccessibleError(m_Watcher);
}

}


静态 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 ;
尝试
{
m_Watcher.EnableRaisingEvents = false ;

if (!Directory.Exists(m_Watcher.Path))
{
Console.WriteLine( 目录不可访问 + m_Watcher.Path + < span class =code-string> 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( 重新启动RaisingEvents Watcher for + _path + < span class =code-string>
at + DateTime.Now.ToString( HH:mm:ss));
}
}
catch (异常错误)
{
Console.WriteLine( 尝试重启服务时出错 + error.StackTrace + at + DateTime.Now.ToString( HH: MM:SS));
m_Watcher.EnableRaisingEvents = false ;
System.Threading.Thread.Sleep(iTimeOut);
}
}
}

}





和代码例如:



观察者观察者; 

watcher = 观察者( @ C:\WORK\TESTING\01 *。*< /跨度>);
watcher.start();
Console.WriteLine( @ 启动Watcher:C:\WORK\TESTING\01 );

watcher = 观察者( @ C:\WORK\TESTING\02 *。*< /跨度>);
watcher.start();
Console.WriteLine( @ 启动Watcher for:C:\WORK\TESTING\02 );

watcher = 观察者( @ T:\ UTILS \ TESTING \ 01 *。*< /跨度>);
watcher.start();
Console.WriteLine( @ 启动Watcher:T:\ UTILS \ TESTING \ 01 );

watcher = 观察者( @ T:\ UTILS \ TESTING \ 02 *。*< /跨度>);
watcher.start();
Console.WriteLine( @ 启动Watcher:T:\ UTILS \ TESTING \ 02 );

while true
{
Thread .Sleep( 5000 );
}





如果我只使用一个obj它工作正常并恢复正常,但如果我实例更多当他得到一个错误时,他不是一个班级的对象:



假设那里有2个(例如)观察者丢失网络,但我能看到的信息是仅适用于我实例化的最新版本。

因此,当自动恢复时,它会为第二个目录创建2个新的观察者。



It看起来这个错误是由2个obj引起的,但只有最新的一个被展位存放和使用。



任何关于我做错的想法?



提前致谢。

解决方案



你重复一遍 NotAccessibleError 中的开始代码。我相信简单地重写 start 会改善你的代码。以下是一个例子。这里 m_Watcher 已被 file_watcher 取代。此外, file_watcher 应该在类变量声明中初始化为null。

  //   *********************** ******************************开始 

public static void start()
{

if (file_watcher!= null
{
file_watcher。创建 - = OnCreated;
file_watcher.Error - = OnError;

file_watcher.Dispose();
file_watcher = null ;
}

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

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



在添加新事件之前,不删除事件处理程序可能会遇到问题。在修订后的开始中,如果 file_watcher 不为空,则通过删除事件处理程序来修复。





通过实施此修订版,所有需要做的就是在 NotAccessibleError 中适当地调用 start()。 />





我将观察者更改为 FileWatcher 。要使修订的开始起作用, FileWatcher 构造函数不应实例化新的 FileSystemWatcher 。以下代码是修订后的类常量,类变量和类构造函数。

  //   ****************************** ***************类FileWatcher  

public class FileWatcher
{

// * ******************************************类常数

const int MAXIMUM_ATTEMPTS = 120 < /跨度>;
const int TIMEOUT = 5000 ;

// **************** ***************************类变量

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;
}



希望有所帮助。


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:

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:

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.

解决方案


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.

// ***************************************************** 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.

// ********************************************* 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.


这篇关于控制来自filesystemwatcher obj的多个实例的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆