FileSystemWatcher:将多个过滤事件聚合成一个?
FileSystemWatcher: aggregate multiple filter events into a single one?
拿下面的代码来说,watcher引发的事件都调用同一个方法:
[NonSerialized]
private FileSystemWatcher Watcher;
private void WatcherInit()
{
Watcher ??= new FileSystemWatcher();
Watcher.Path = Application.dataPath;
Watcher.Filter = "*.mat";
Watcher.IncludeSubdirectories = true;
Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.CreationTime;
Watcher.EnableRaisingEvents = true;
Watcher.Changed += OnWatcherChanged;
Watcher.Created += OnWatcherCreated;
Watcher.Deleted += OnWatcherDeleted;
Watcher.Renamed += OnWatcherRenamed;
}
private void OnWatcherRenamed(object sender, RenamedEventArgs args)
{
DoViewReload();
}
private void OnWatcherDeleted(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
private void OnWatcherCreated(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
private void OnWatcherChanged(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
这导致同一方法被多次调用,而我希望它只被调用一次。
在我的例子中,我刷新了 UI,当我创建一个新文件时它发生了 3 次。
我想应该有一些计时器可以等待连续的事件并连接它们,然后只发出一个调用;这只是一个猜测,也许还有我不知道的更好的解决方案。
有什么想法吗?
以下模式最终运行良好:
private void OnWatcherRenamed(object sender, RenamedEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherDeleted(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherCreated(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherChanged(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void WatcherTimerRestart()
{
WatcherTimer.Enabled = false;
WatcherTimer.Enabled = true;
}
private void WatcherTimerCallback(object sender, ElapsedEventArgs e)
{
// do the funky stuff you wanted to execute only once
}
备注:
我决定将 UI 切换到特定状态,例如:
Waiting for I/O to complete...
并且在这种情况下,将间隔设置为不太低的值(例如 3000 毫秒)会更好:
- 用户有时间阅读消息
- 实践证明较低的值是不够的,即使是小文件 and/or SSD
FileSystemWatcher
引发事件的速度很慢
下面是关于根据用户操作引发的事件的迷你table:
User action
Callbacks raised
Create
Created
Delete
Changed, Deleted
Rename
Changed, Created, Deleted
Move
Changed, Created, Deleted
您可能需要注意,具有讽刺意味的是,即使对于重命名操作,也根本不会引发 Renamed
;这可能与应用程序如何重命名文件有关,有多种方法可以做到这一点。
拿下面的代码来说,watcher引发的事件都调用同一个方法:
[NonSerialized]
private FileSystemWatcher Watcher;
private void WatcherInit()
{
Watcher ??= new FileSystemWatcher();
Watcher.Path = Application.dataPath;
Watcher.Filter = "*.mat";
Watcher.IncludeSubdirectories = true;
Watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.CreationTime;
Watcher.EnableRaisingEvents = true;
Watcher.Changed += OnWatcherChanged;
Watcher.Created += OnWatcherCreated;
Watcher.Deleted += OnWatcherDeleted;
Watcher.Renamed += OnWatcherRenamed;
}
private void OnWatcherRenamed(object sender, RenamedEventArgs args)
{
DoViewReload();
}
private void OnWatcherDeleted(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
private void OnWatcherCreated(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
private void OnWatcherChanged(object sender, FileSystemEventArgs args)
{
DoViewReload();
}
这导致同一方法被多次调用,而我希望它只被调用一次。
在我的例子中,我刷新了 UI,当我创建一个新文件时它发生了 3 次。
我想应该有一些计时器可以等待连续的事件并连接它们,然后只发出一个调用;这只是一个猜测,也许还有我不知道的更好的解决方案。
有什么想法吗?
以下模式最终运行良好:
private void OnWatcherRenamed(object sender, RenamedEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherDeleted(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherCreated(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void OnWatcherChanged(object sender, FileSystemEventArgs args)
{
WatcherTimerRestart();
}
private void WatcherTimerRestart()
{
WatcherTimer.Enabled = false;
WatcherTimer.Enabled = true;
}
private void WatcherTimerCallback(object sender, ElapsedEventArgs e)
{
// do the funky stuff you wanted to execute only once
}
备注:
我决定将 UI 切换到特定状态,例如:
Waiting for I/O to complete...
并且在这种情况下,将间隔设置为不太低的值(例如 3000 毫秒)会更好:
- 用户有时间阅读消息
- 实践证明较低的值是不够的,即使是小文件 and/or SSD
FileSystemWatcher
引发事件的速度很慢
下面是关于根据用户操作引发的事件的迷你table:
User action | Callbacks raised |
---|---|
Create | Created |
Delete | Changed, Deleted |
Rename | Changed, Created, Deleted |
Move | Changed, Created, Deleted |
您可能需要注意,具有讽刺意味的是,即使对于重命名操作,也根本不会引发 Renamed
;这可能与应用程序如何重命名文件有关,有多种方法可以做到这一点。