// 初始化 file system watcher
[SecuritySafeCritical]
private ManualResetEvent Initialize()
{
ManualResetEvent initLoadEvent = new ManualResetEvent(false)
; FileInfo filePath = new FileInfo(this.Path);
this.fileWatcher = new FileSystemWatcher(filePath.DirectoryName, filePath.Name);
this.fileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
// 第一次读取的时候使用单独的线程来load文件
ThreadPool.QueueUserWorkItem(s => {
this.UpdateFile()
; this.fileWatcher.EnableRaisingEvents = true;
initLoadEvent.Set();
});
return initLoadEvent;
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
this.UpdateFile();
}
// 文件更新的时候处理方法 private void UpdateFile()
{
try
{
if (File.Exists(this.Path))
{
T newValue;
using (FileStream readStream = new FileStream(this.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
try
{
newValue = this.readMethod(readStream); // 这里使用的readmethod就是你传入loadData自定义处理方法
}
catch (IOException)
{
// Error occurred at the file system level - handle with top
throw;
}
catch (Exception readMethodEx)
{
this.LastFailedLoadTime = DateTime.MaxValue;
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Error occured while parsing a watched file: {0}", this.Path),
String.Empty, readMethodEx);
return;
}
}
this.LastFailedLoadTime = DateTime.MaxValue;
this.Value = newValue;
}
}
catch (IOException ioEx)
{
if (this.LastFailedLoadTime == DateTime.MaxValue)
{
this.LastFailedLoadTime = DateTime.UtcNow;
}
else if (this.LastFailedLoadTime == DateTime.MinValue)
{
return;
}
else if (DateTime.UtcNow - this.LastFailedLoadTime >= FailedLoadGracePeriod)
{
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Unable to access watched file after ({0}): {1}", FailedLoadGracePeriod, this.Path),
String.Empty, ioEx);
this.LastFailedLoadTime = DateTime.MinValue;
}
}
catch (Exception ex)
{
this.LastFailedLoadTime = DateTime.MaxValue;
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Unable to retrieve watched file: {0}", this.Path),
String.Empty, ex);
}
}}
[SecuritySafeCritical]
private ManualResetEvent Initialize()
{
ManualResetEvent initLoadEvent = new ManualResetEvent(false)
; FileInfo filePath = new FileInfo(this.Path);
this.fileWatcher = new FileSystemWatcher(filePath.DirectoryName, filePath.Name);
this.fileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
// 第一次读取的时候使用单独的线程来load文件
ThreadPool.QueueUserWorkItem(s => {
this.UpdateFile()
; this.fileWatcher.EnableRaisingEvents = true;
initLoadEvent.Set();
});
return initLoadEvent;
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
this.UpdateFile();
}
// 文件更新的时候处理方法 private void UpdateFile()
{
try
{
if (File.Exists(this.Path))
{
T newValue;
using (FileStream readStream = new FileStream(this.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
try
{
newValue = this.readMethod(readStream); // 这里使用的readmethod就是你传入loadData自定义处理方法
}
catch (IOException)
{
// Error occurred at the file system level - handle with top
throw;
}
catch (Exception readMethodEx)
{
this.LastFailedLoadTime = DateTime.MaxValue;
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Error occured while parsing a watched file: {0}", this.Path),
String.Empty, readMethodEx);
return;
}
}
this.LastFailedLoadTime = DateTime.MaxValue;
this.Value = newValue;
}
}
catch (IOException ioEx)
{
if (this.LastFailedLoadTime == DateTime.MaxValue)
{
this.LastFailedLoadTime = DateTime.UtcNow;
}
else if (this.LastFailedLoadTime == DateTime.MinValue)
{
return;
}
else if (DateTime.UtcNow - this.LastFailedLoadTime >= FailedLoadGracePeriod)
{
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Unable to access watched file after ({0}): {1}", FailedLoadGracePeriod, this.Path),
String.Empty, ioEx);
this.LastFailedLoadTime = DateTime.MinValue;
}
}
catch (Exception ex)
{
this.LastFailedLoadTime = DateTime.MaxValue;
this.logger.Error("FileWatcher.UpdateFile",
String.Format(CultureInfo.InvariantCulture, "Unable to retrieve watched file: {0}", this.Path),
String.Empty, ex);
}
}}
总结
该类主要使用了FileSystemWatcher,异常控制,事件Handler,委托等大家都熟知的方式组合起来来实现,个人感觉确实还可以,主要是我喜欢直接通过静态变量来用这种方式,而不需要另外单独写初始化代码。
不过这个类,不是大叔写的,而是Onsite Team里的一个同事写的(此人曾在微软工作过11年),其实总结起来没有什么比较特殊的知识,只是我们被平时的项目压得没时间思考而已,我相信博客园的一些有经验的人如果有充分的时间也能想出更好的方式来。