解决FileSystemWatcher事件多次触发的方法

解决FileSystemWatcher事件多次触发的方法

作者: 江大鱼 发表于 2008-07-23 21:55 原文链接 阅读: 968 评论: 2

 

博客园已有几位同学发表了关于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

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

解决FileSystemWatcher事件多次触发的方法

评论: 2 查看评论 发表评论

软件研发团队管理年会(上海,7.10-7.11)


最新新闻:
· 6个强大的社会化网络搜索引擎(2010-06-12 08:58)
· 马雪征:把联想的经验带入TPG(2010-06-12 08:54)
· 苹果如何基业长青(2010-06-12 08:52)
· 腾讯:平台优势催动“利润发生器”(2010-06-12 08:52)
· Google News测试新版页面(2010-06-12 08:50)

编辑推荐:谈谈IT软件开发工程师的基本功

网站导航:博客园首页  个人主页  新闻  闪存  小组  博问  社区  知识库

转载于:https://my.oschina.net/kjiang/blog/5515

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110764.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号