zoukankan      html  css  js  c++  java
  • FileSystemWatcher事件多次触发的解决方法

     转自:http://www.cnblogs.com/dragon/archive/2008/07/04/filesystemwatcher.html
    1、问题描述
         
    程序里需要监视某个目录下的文件变化情况: 一旦目录中出现新文件或者旧的文件被覆盖,程序需要读取文件内容并进行处理。于是使用了下面的代码:
    public void Initial()
    {
       System.IO.FileSystemWatcher fsw 
    = new System.IO.FileSystemWatcher();            
       fsw.Filter 
    = "*.*";
       fsw.NotifyFilter 
    = NotifyFilters.FileName  | 
                          NotifyFilters.LastWrite 
    | 
                          NotifyFilters.CreationTime;

       
    // Add event handlers.
       fsw.Created += new FileSystemEventHandler(fsw_Changed);
       fsw.Changed 
    += new FileSystemEventHandler(fsw_Changed);

       
    // Begin watching.
       fsw.EnableRaisingEvents = true;
    }

     
    void fsw_Changed(object sender, FileSystemEventArgs e)
    {
       MessageBox.Show(
    "Changed", e.Name);
    }
    结果发现当一个文件产生变化时,Change事件被反复触发了好几次。这样可能的结果是造成同一文件的重复处理。
    2、解决方案:
    在Google上进行一番搜索后,得到了下面的一段信息: <<http://www.cnblogs.com/RicCC/archive/2006/12/16/filesystem-watcher.html>>
    "...可以参考log4net的做法。通过一个计时器,在文件事件处理中让计时器延迟一段时间之后,再执行加载新的配置文件操作。这样可以避免对文件做一次操作触发了多个更改事件,而多次加载配置文件。"

    研究了log4net的代码 - XmlConfigurator.cs,然后参照log4net对代码作了如下改动:
    基本思想是使用定时器,在事件触发时开始启动定时器,并记下文件名。当定时器到时,才真正对文件进行处理。
    (1). 定义变量

    private int TimeoutMillis = 2000//定时器触发间隔
    System.IO.FileSystemWatcher fsw = new System.IO.FileSystemWatcher();
    System.Threading.Timer m_timer 
    = null;
    List
    <String> files = new List<string>(); //记录待处理文件的队列
    (2). 初始化FileSystemWatcher和定时器
    fsw.Filter = "*.*";
    fsw.NotifyFilter 
    = NotifyFilters.FileName  | 
                         NotifyFilters.LastWrite 
    | 
                         NotifyFilters.CreationTime;

    // Add event handlers.
    fsw.Created += new FileSystemEventHandler(fsw_Changed);
    fsw.Changed 
    += new FileSystemEventHandler(fsw_Changed);

    // Begin watching.
    fsw.EnableRaisingEvents = true;

    // Create the timer that will be used to deliver events. Set as disabled
    if (m_timer == null)
    {
          
    //设置定时器的回调函数。此时定时器未启动
          m_timer = new System.Threading.Timer(new TimerCallback(OnWatchedFileChange),  null, Timeout.Infinite, Timeout.Infinite);
    }

    (3). 文件监视事件触发代码:修改定时器,记录文件名待以后处理

    void fsw_Changed(object sender, FileSystemEventArgs e)
    {
        Mutex mutex 
    = new Mutex(false"FSW");
        mutex.WaitOne();
        
    if (!files.Contains(e.Name))
          
    {
            files.Add(e.Name);
        }

        mutex.ReleaseMutex();

        
    //重新设置定时器的触发间隔,并且仅仅触发一次
        m_timer.Change(TimeoutMillis, Timeout.Infinite);
    }

    (4). 定时器事件触发代码:进行文件的实际处理

    private void OnWatchedFileChange(object state)
    {
        List
    <String> backup = new List<string>();

        Mutex mutex 
    = new Mutex(false"FSW");
        mutex.WaitOne();
        backup.AddRange(files);
        files.Clear();
        mutex.ReleaseMutex();
        
        
    foreach (string file in backup)
          
    {
            MessageBox.Show(
    "File Change", file + " changed");
        }

    }

    完整的代码请下载示例程序


    To be the apostrophe which changed “Impossible” into “I’m possible”
    ----------------------------------------------------
    WinkingZhang's Blog (http://winkingzhang.cnblogs.com)
    GCDN(http://gcdn.grapecity.com/cs)
  • 相关阅读:
    Representation Data in OpenCascade BRep
    Render OpenCascade Geometry Surfaces in OpenSceneGraph
    Render OpenCascade Geometry Curves in OpenSceneGraph
    OpenCascade Shape Representation in OpenSceneGraph
    Geometry Surface of OpenCascade BRep
    Geometry Curve of OpenCascade BRep
    Tyvj2017清北冬令营入学测试
    Spfa算法模板
    洛谷1016 旅行家的预算
    洛谷1290 欧几里得的游戏
  • 原文地址:https://www.cnblogs.com/winkingzhang/p/1235286.html
Copyright © 2011-2022 走看看