您的位置:首页 > 其它

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

2010-06-12 10:01 531 查看
作者: 江大鱼 发表于 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 m_DictUpdateTime = new Dictionary();
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的性能会随着文件数量的增加而降低。

<div style="border: 2px solid silver; padding: 3px;
line-height: 20px; background-color: #e1e1e1; width: 700px;"
class="signature">作者:<a
href="江大鱼">http://jzywh.cnblogs.com/">江大鱼

出处:http://jzywh.cnblogs.com

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


评论: 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软件开发工程师的基本功

网站导航:博客园首页  个人主页  新闻  闪存  小组  博问  社区  知识库
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: