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

    博客园已有几位同学发表了关于FileSystemWatcher事件多次触发的解决方法的文章,很好地解决了事件多次激发的问题。

    主要方法有:

    1.延迟激发法。

    http://www.cnblogs.com/dragon/archive/2008/07/04/filesystemwatcher.html

    原理是延迟调用事件的代理,将多次事件合并为一次,从而很好的解决了此问题,唯一的缺憾是时间激发不及时,不适用于实时性较高的系统。




    2.临时禁用法。

     1: void watcher_Changed(object sender, FileSystemEventArgs e) 
     2: { 
     3: if (watcher != null) 
     4: { 
     5: //解决执行两次的问题 
     6: watcher.EnableRaisingEvents = false; 
     7: Thread th = new Thread(new ThreadStart( 
     8: delegate() 
     9: { 
     10: Thread.Sleep(1000); 
     11: watcher.EnableRaisingEvents = true; 
     12: } 
     13: )); 
     14: th.Start(); 
     15: } 
     16: } 

    这种方法是监视单个文件的情况下的最简单解决办法。但是很明显,在监视多个文件的情况下就有很大的问题,文件的事件很可能丢失,在高并发的情况下很容易出问题。


     

    我这里要提出的新的方法叫“检查最后更新时间法”,原理是在FileSystemWatcher事件激发时先检查更新的文件的最后更新时间是否已经被记录, 如果未被记录则激发event,否则不激发。

    具体代码如下

     1: using System;
     2: using System.Collections.Generic;
     3: using System.Linq;
     4: using System.Text;
     5: using System.IO;
     6:  
     7: namespace GiantSoft.Common
     8: {
     9: public class GiantFileSystemWatcher : IDisposable
     10: {
     11: private FileSystemWatcher m_Watcher;
     12:  
     13: private Dictionary<string, DateTime> m_DictUpdateTime = new Dictionary<string, DateTime>();
     14:  
     15: public GiantFileSystemWatcher(string path, string filter)
     16: {
     17: m_Watcher = new FileSystemWatcher(path, filter);
     18: m_Watcher.Error += new ErrorEventHandler(m_Watcher_Error);
     19: m_Watcher.EnableRaisingEvents = false;
     20: m_Watcher.IncludeSubdirectories = true;
     21: }
     22:  
     23: void m_Watcher_Error(object sender, ErrorEventArgs e)
     24: {
     25: LogUtil.LogError(e.GetException());
     26: }
     27:  
     28: public bool Start()
     29: {
     30: if (m_FileChangeHandler != null)
     31: {
     32: m_Watcher.Changed += new FileSystemEventHandler(m_Watcher_Changed);
     33: m_Watcher.Created += new FileSystemEventHandler(m_Watcher_Changed);
     34: m_Watcher.Renamed += new RenamedEventHandler(m_Watcher_Changed);
     35: m_Watcher.EnableRaisingEvents = true;
     36: return true;
     37: }
     38: else
     39: {
     40: return false;
     41: }
     42: }
     43:  
     44: void m_Watcher_Changed(object sender, FileSystemEventArgs e)
     45: {
     46: try
     47: {
     48: DateTime lastModifyTime = File.GetLastWriteTime(e.FullPath);
     49: DateTime prevModifyTime = DateTime.MinValue;
     50:  
     51: if (m_DictUpdateTime.TryGetValue(e.FullPath.ToLower(), out prevModifyTime))
     52: {
     53: if (lastModifyTime <= prevModifyTime)
     54: {
     55: return;
     56: }
     57: else
     58: {
     59: m_DictUpdateTime[e.FullPath.ToLower()] = lastModifyTime;
     60: }
     61: }
     62: else
     63: {
     64: m_DictUpdateTime[e.FullPath.ToLower()] = lastModifyTime;
     65: }
     66:  
     67: if (m_FileChangeHandler != null)
     68: {
     69: m_FileChangeHandler.Invoke(this, e);
     70: }
     71: }
     72: catch (Exception exc)
     73: {
     74: LogUtil.LogError(exc);
     75: }
     76: }
     77:  
     78: private FileSystemEventHandler m_FileChangeHandler;
     79:  
     80: public event FileSystemEventHandler FileChangeHandler
     81: {
     82: add { m_FileChangeHandler += value; }
     83: remove { m_FileChangeHandler -= value; }
     84: }
     85:  
     86: #region IDisposable Members
     87:  
     88: public void Dispose()
     89: {
     90: m_DictUpdateTime.Clear();
     91: m_DictUpdateTime = null;
     92: m_Watcher.EnableRaisingEvents = false;
     93: if (m_FileChangeHandler != null)
     94: {
     95: m_Watcher.Changed -= new FileSystemEventHandler(m_Watcher_Changed);
     96: m_Watcher.Created -= new FileSystemEventHandler(m_Watcher_Changed);
     97: m_Watcher.Renamed -= new RenamedEventHandler(m_Watcher_Changed);
     98: }
     99: m_Watcher.Dispose();
     100: }
     101:  
     102: #endregion
     103: }
     104: }

    这种解决方法能够满足绝大部分的需求,但是对于监视数量巨大的文件会有性能问题,Dictionary的性能会随着文件数量的增加而降低。


    作者:江大鱼
    出处:http://jzywh.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    LeetCode: 18. 4Sum
    LeetCode:15. 3Sum
    Leetcode:1. Two Sum
    tensorflow placeholder
    Tensorflow变量
    13.git的简单使用
    13.Django1.11.6文档
    12.python进程协程异步IO
    12.Flask-Restful
    12.Django思维导图
  • 原文地址:https://www.cnblogs.com/jzywh/p/filesystemwatcher.html
Copyright © 2011-2022 走看看