FileSystemWatcher:将多个过滤器事件聚合为单个事件?



以下面的代码为例,监视器引发的事件都调用相同的方法:

[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 ms,效果会更好:

  • 用户有时间读取消息
  • 一个较低的值在实践中被证明是不够的,即使在小文件和/或SSD
  • FileSystemWatcher触发事件缓慢

这里是一个关于根据用户操作引发的事件的迷你表:

tbody> <<tr>
用户操作引发的回调
创建创建
删除改变,删除
重命名修改、创建、删除
改变,创建、删除

最新更新