FileSystemWatcher之错误处理
来源:互联网 发布:越南芽庄网络怎么样 编辑:程序博客网 时间:2024/06/05 04:41
http://www.cnblogs.com/challengerking/articles/468050.html
一.前言
我们知道FileSystemWatcher 类用来侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。 在我们刚刚结束的项目当中也用到.NET的这个类。关于这个类的使用诸多帮助文档和搏友们都有过精彩的描述。
我们现在大概回顾一下这个类的基本特性:使用 FileSystemWatcher 监视指定目录中文件的创建,更改,删除,也可监视指定目录中的文件或子目录的创建,更改,删除等事件。可以创建一个组件来监视本地计算机、网络驱动器或远程计算机上的文件。可监视目录或文件中的若干种更改。例如,可监视文件或目录的 Attributes、LastWrite 日期和时间或 Size 方面的更改。通过将NotifyFilter 属性设置为 NotifyFilters 值之一来达到此目的。有关可监视的更改类型的更多信息。
不过关于FileSystemWatcher类的错误处理部分,资料却显得相对少很多,MSDN上也几乎没有给出相关的介绍和例子。比如我们用FileSystemWatcher类来监控一个局域网或者远程机器的一个目录,在软件运行的情况下,网络突然出现问题,抑或,远程监控的目录被删除的情况下,即便此时网络恢复,或远程目录重建,FileSystemWatcher 也无法恢复正常工作状态。所以FileSystemWatcher类就应该有相应的处理,使得FileSystemWatcher对象从错误中恢复,对接下来发生的创建,更改,删除 等事件做出响应。
二.正文
下面我们来看一下几段程序,在接下来的描述中来体会FileSystemWatcher错误处理的一个简单实例。希望能有用处。
在一般性的项目中,对于出现网络不通等错误时,需要进行重试,以便通过重试将系统从错误当中恢复。那么我们先来介绍一个用C#写的来进行局域网中的重试方法,这个方法将会在后面的方法中用到。
2/// Checks the Temporary folder connection when application start. If can't connect,
3/// this method will retry to connect, using the specified retry number and
4/// retry interval time in configuration file.
5///</summary>
6///<returns>Returns true if successfully connect to folder.
7/// Returns false if can't connect to folder after retrying.</returns>
8publicbool CheckMonitorPath(string strMonitorPath, int nRetryInterval,int nMaxRetryCount)
9{
10// The temporary folder path existence flag
11bool bTemporaryPathExist=false;
12
13if (!Directory.Exists(strMonitorPath))
14{
15if (nMaxRetryCount<0)
16{
17// Retry to connect the Temporary folder
18 CLogger.log.Info("MSG_INFO_STARTUP_CONNECT", strMonitorPath);
19int i =0;
20for (; ; i++)
21{
22if (RetryConnectFolder(i, nRetryInterval, strMonitorPath))
23{
24 bTemporaryPathExist=true;
25break;
26 }
27 }
28 }
29else
30{
31// Retry to connect the Temporary folder
32 CLogger.log.Info("MSG_INFO_STARTUP_CONNECT", strMonitorPath);
33int i =0;
34for (; i < nMaxRetryCount; i++)
35{
36if (RetryConnectFolder(i, nRetryInterval, strMonitorPath))
37{
38 bTemporaryPathExist=true;
39break;
40 }
41 }
42if (nMaxRetryCount== i)
43{
44 CLogger.log.Error("MSG_ERROR_RETRYCONNECTFAILED", strMonitorPath, i.ToString());
45 bTemporaryPathExist=false;
46 }
47 }
48 }
49else
50{
51 bTemporaryPathExist=true;
52 }
53return bTemporaryPathExist;
54 }
55
56/**////<summary>
57/// Retry to connect the monitoring folder
58///</summary>
59///<param name="nCounter">The retry time</param>
60///<param name="nRetryInterval">The retry interval time</param>
61///<param name="strMonitorPath">The monitored path retry to connect</param>
62///<returns>true: retry connect success, false: retry connect failed</returns>
63privatebool RetryConnectFolder(int nCounter, int nRetryInterval,string strMonitorPath)
64{
65if (0!= nCounter)
66{
67 CLogger.log.Debug("MSG_DEBUG_STARTUP_CONNECT_RETRY", nCounter.ToString());
68 }
69else
70{
71 CLogger.log.Debug("MSG_DEBUG_STARTUP_CONNECT_RETRY", strMonitorPath);
72 }
73try
74{
75if (Directory.Exists(strMonitorPath))
76{
77// If the Temporary folder connect successfully
78 CLogger.log.Info("MSG_INFO_STARTUP_CONNECT_RETRYSUCCESS", strMonitorPath, nCounter.ToString());
79returntrue;
80 }
81 }
82catch (Exception ex)
83{
84 CLogger.log.Error("MSG_ERROR_RETRYCONNECT_EXCEPTION", ex);
85returnfalse;
86 }
87// Retry to connect the temporary folder with certain interval time
88 Thread.Sleep(nRetryInterval*1000);
89returnfalse;
90}
91
接下来的这个方法是对FileSystemWatcher类的使用,其中包括将要监控的文件夹路径,可监视文件或目录的 Attributes、LastWrite 日期和时间或 Size 方面的更改。通过将FileSystemWatcher.NotifyFilter 属性设置为 NotifyFilters 值之一来达到此目的。有关可监视的更改类型的更多信息。
2/// The watcher method, to sense whether there is new file
3/// is created in the network/local folder
4///</summary>
5publicvoid SystemWatch()
6{
7try
8{
9 watcher.Path= RemoteMonitorPath;
10 watcher.NotifyFilter= NotifyFilters.LastWrite| NotifyFilters.FileName;
11// Sub-folder of the root can be monitored
12 watcher.IncludeSubdirectories=true;
13 watcher.Filter="*.*";
14 watcher.Created+=new FileSystemEventHandler(OnChanged);
15// Add the event handlers: this event raised when it detects an error
16 watcher.Error+=new ErrorEventHandler(WatcherError);
17 watcher.EnableRaisingEvents=true;
18
19 CLogger.log.Info("MSG_INFO_WATCHER_START");
20while (!bStop)
21{
22 oEvent.WaitOne();
23 }
24 CLogger.log.Info("MSG_INFO_WATCHER_STOP");
25 }
26catch (ArgumentException ex)
27{
28 CLogger.log.Error("MSG_ERROR_WATCHER_RUNTIMEEXCEPTION", ex);
29 }
30catch (FileNotFoundException ex)
31{
32 CLogger.log.Error("MSG_ERROR_WATCHER_RUNTIMEEXCEPTION", ex);
33 }
34catch (DirectoryNotFoundException ex)
35{
36 CLogger.log.Error("MSG_ERROR_WATCHER_RUNTIMEEXCEPTION", ex);
37 }
38catch (Exception ex)
39{
40 CLogger.log.Error("MSG_ERROR_WATCHER_RUNTIMEEXCEPTION", ex);
41 }
42 }
43
下面这个函数就是本文的重点,是FileSystemWatcher类的错误处理的函数,当发生监控路径错误时(网络问题,或者所监控文件夹被删除等),FileSystemWatcher类会自动捕捉错误,然后这个函数被调用,将FileSystemWatcher类从死亡中拯救出来。
2/// The error event handler
3///</summary>
4///<param name="source">The object instance</param>
5///<param name="e">The ErrorEventArgs instance</param>
6privatevoid WatcherError(object source, ErrorEventArgs e)
7{
8// Retry interval and max retry time (times)
9 nRetryInterval= alertConfigValues.TempConnectInterval;
10 nMaxRetryCount= alertConfigValues.TempMaxRetryCount;
11try
12{
13 Exception watchException= e.GetException();
14 CLogger.Log.Error("MSG_ERROR_FILESYSTEMWATCHER_ERROROCCURS", watchException.Message);
15
16if (netSniffer.CheckMonitorPath(RemoteMonitorPath, nRetryInterval, nMaxRetryCount))
17{
18int nRetryCounter=0;
19// We need to create new version of the object because the
20// old one is now corrupted
21 watcher=new FileSystemWatcher();
22while (!watcher.EnableRaisingEvents)
23{
24try
25{
26// This will throw an error at the
27// watcher.NotifyFilter line if it can't get the path.
28 SystemWatch();
29 Thread.Sleep(nRetryInterval*1000);
30 nRetryCounter++;
31
32if (nMaxRetryCount== nRetryCounter)
33{
34break;
35 }
36 }
37catch
38{
39// Sleep for a while; otherwise, it takes a bit of
40// processor time
41 Thread.Sleep(nRetryInterval*1000);
42 }
43 }
44// Stop the watcher
45 CLogger.Log.Error("MSG_ERROR_FILESYSTEMWATCHER_RETRYFAILED");
46 }
47else
48{
49// Stop the watcher
50 CLogger.Log.Error("MSG_ERROR_FILESYSTEMWATCHER_RETRYFAILED");
51 }
52 }
53catch (Exception ex)
54{
55 CLogger.Log.Error("MSG_ERROR_FILESYSTEMWATCHER_ERROROCCURS", ex);
56 }
57 }
58
通过对于错误的处理FileSystemWatcher又活过来了,这下它又可以正常工作了。我们可以直观地看一个截图。
三.后记
当初也是因为在做项目的时候遇到这个问题,即便恢复网络连接/重建文件夹FileSystemWatcher却无法再工作了,在百般苦恼与挣扎中才找到解决的办法,其实微软本来就提供的关于Error事件处理的使用办法,只不过没有明确讲明白其用法而已。
我写这篇短短小文的初衷,也仅仅是为了记录一下所谓心路历程,在工作的过程中,这个问题给我留下了很深的映像,同时也希望博友们如果遇到相似问题,这篇小文也许会有一些用处。- FileSystemWatcher之错误处理
- Discovery Cab Tool 之FileSystemWatcher
- JavaScript之错误处理
- JS之错误处理
- LR之错误处理
- RxJava之错误处理
- PHP之错误处理
- Javascript 错误处理之抛出自定义错误
- Javascript 之错误处理篇
- 学习笔记之错误处理
- Win32多线程之错误处理
- kettle常见问题之错误处理
- linux C++之错误处理
- Kettle学习之错误处理
- PHP之错误处理技巧
- javascript之处理Ajax错误
- 《openssl 编程》之错误处理
- objective-c之错误处理
- 简明 Vim 练级攻略
- UNIX程序设计实验三 目录树的遍历
- Linux shell编程入门
- POI LastRowNum and PhysicalNumberOfRows
- Oralce中的to_date()函数
- FileSystemWatcher之错误处理
- android 简单动画实现
- 直接获取访问者的当前城市
- USACO / Subset Sums集合 (DP)
- 排序
- WinCE开机Logo的实现(USB下载图片到nandflash)
- Building NetCDF* with the Intel® Compilers
- 网络5——传输层
- mysql上课笔记(一)