作者: 江大鱼 发表于 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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
最新新闻:
· 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账号...