繁体   English   中英

FileSystemWatcher,取消订阅活动

[英]FileSystemWatcher, unsubscribe from the event

我在搞怪4.0中的FileSystemWatcher。 我觉得这很有用,但是陷入了循环。 我试图监视ini更改的时间,并将其更改回正确的默认值(冗长的故事),但是复制新文件的更改事件导致其陷入循环...任何想法>? 为了避免触发更改的事件,我尝试删除并重新创建文件,但是这导致了我希望避免的程序问题。 我也想像我可以覆盖文本,但这也带来了同样的问题。 先谢谢您的帮助

  static void Main() { Watch (@"\\NoFault2010\Lexis\Data\Setup\", "tmconfig.ini", true); }

        static void Watch (string path, string filter, bool includeSubDirs)
        {
            using (var watcher = new FileSystemWatcher (path, filter))
            {

                watcher.Changed += FileChanged;

                watcher.EnableRaisingEvents = true;

                Console.WriteLine("Do Not Close ... \n\nThis is a Temporary Configuration Manager for Time Matters ... \n\n\nI'm Listening ............");
                Console.ReadLine();
            }
        }

    static void FileChanged (object o, FileSystemEventArgs e)
    {
        string _right_stuff = @"\\NOFAULT2010\Lexis\Data\Templates\Programs\tmconfig.ini";
        string _working = @"\\NOFAULT2010\Lexis\Data\Setup\tmconfig.ini";

        System.Threading.Thread.Sleep(2000);

        File.Copy(_right_stuff, _working, true);

        Console.WriteLine("File {0} has been {1}", e.FullPath, e.ChangeType);
        MAIL_IT("SQLMail@lcjlawfirm.com", "TM Master.INI has been altered", "Check the Master INI and Yell At Ecopy Guy " + e.ChangeType + e.FullPath);

    }

我将如何退订该事件以避免进入此循环。

要在自己摆弄文件时临时禁用该事件,请执行以下操作:

static void FileChanged (object o, FileSystemEventArgs e)
{  
    watcher.Changed -= FileChanged; 

    ... correct the file here...

    watcher.Changed += FileChanged; 
}

另外,您可以使用保护变量来检测可重入调用:

static bool reentrant = false;
static void FileChanged (object o, FileSystemEventArgs e)
{  
    if (reentrant)
        return;

    reentrant = true;

    ... correct the file here...

    reentrant = false;
}

请注意,您还需要在方法中进行异常处理,否则,如果发生问题,文件观察器可能会被永久禁用。

我编写了一个依赖于filesystemwatcher的应用程序-而且,有时fsw处理程序会对文件进行更改。 我以两种方式进行处理-第一种是认为我的代码可以非常快速地更改文件-所以我做到了

fsw.EnableRaisingEvents = false; 
//make my change
fsw.EnableRaisingEvents = true; 

但是,如果您认为在此期间可能会更改其他文件,则可以记录进行更改的时间并将该数据存储在某处...

例如,字典mapFileNameTimeChanged ...在这里您可以存储文件名...因此在处理程序中您可以执行以下操作...。

fsw_Changed(object sender, FileSystemEventArgs e)
{
    lock (m_mapFileNameChanged)
    {
        if (m_mapFileNameChanged.ContainsKey(e.FullPath))
        {
            FileInfo fileInfo = new FileInfo(e.FullPath);
            if (fileInfo.LastAccessTime == m_mapFileNameChanged[e.FullPath]
            {
                return;//not been changed since you last did something with it....
            }
        }
        else
        {
            m_mapFileNameChanged.Remove(e.FullPath);//discard this now..it has changed since you last looked at it...need to look at it again!
        }
    }

    //do things in your event handler...
    lock (m_mapFileNameChanged)
    {
        // copy or change the file here...
        FileInfo fileInfo = new FileInfo(e.FullPath);
        m_mapFileNameChanged[strFullPathToFile] = fileInfo.LastAccessTime;
    }
}

您可以添加一个布尔值(同样在类级别),该布尔值可用于跟踪更改是否是由您引起的,如果是,则立即退出FileChanged方法,即:

static bool inEdit;
static void FileChanged (object o, FileSystemEventArgs e)
{
    if (inEdit)
        return;
    inEdit = true;

    // Do processing

    inEdit = false;
}

退订很容易,所以我想知道这是否是问题:

watcher.Changed -= FileChanged

另外,我将为观察者创建一些对象作为SynchronizationObject。 默认情况下存在一个问题,即观察程序会在新线程中引发事件,因此,如果在创建新线程后取消订阅,则可能会遇到问题。

还要注意的是,FileSystemWatcher可能会为您认为是单个事件的某些事件引发多个事件,并且可能会影响程序的功能。

如果使观察者成为类变量而不是局部变量,则您的FileChanged方法应该可以访问它。 那你应该可以做类似的事情

static void FileChanged (object o, FileSystemEventArgs e) 
{
     watcher.EnableRaisingEvents = false;
     // Edit the file here
     watcher.EnableRaisingEvents = true;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM