这是 FindFirstChangeNotification() Win32 API 从第一天(从 Windows 3.x 开始)以来的一个令人抓狂的怪癖,看起来 FileSystemWatcher 只是简单地包装了该 API。计时器方法(如上所示)是常见的解决方法。
我通常创建一个包装 FileSystemWatcher 并进行多次更改调用过滤的类。编写一些额外的工作,但它在重用中得到了回报。
public class FileChangeMonitor
{
private FileSystemWatcher _fsw;
DateTime _lastEventTime;
public event FileSystemEventHandler Changed;
public FileChangeMonitor(string path, string filter)
{
_fsw = new FileSystemWatcher(path, filter);
_fsw.Changed += new FileSystemEventHandler(_fsw_Changed);
_fsw.EnableRaisingEvents = true;
_fsw.NotifyFilter = NotifyFilters.LastWrite;
_fsw.IncludeSubdirectories = false;
}
private void _fsw_Changed(object sender, FileSystemEventArgs e)
{
// Fix the FindFirstChangeNotification() double-call bug
if (DateTime.Now.Subtract(_lastEventTime).TotalMilliseconds > 100)
{
_lastEventTime = DateTime.Now;
if (this.Changed != null)
this.Changed(sender, e); // Bubble the event
}
}
}
然后,您可以像使用 FileSystemWatcher 一样使用 FileChangeMonitor:
FileChangeMonitor fcm = new FileChangeMonitor(path, filter);
fsm.Changed += new FileSystemEventHandler(fsm_Changed);
...
当然,上面的代码只处理 Changed 事件和 NotifyFilters.LastWrite,但你明白了。