Take the following code, the events raised by the watcher all call the same method:
[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();
}
This results in the same method called multiple times while I'd like it to be only once.
In my case, I refresh the UI and it happens 3 times when I create a new file.
I suppose there should be some timer that would wait for successive events and concat them, then only emit a single call; that's just a guess and maybe there's a better solution around that I'm not aware of.
Any ideas?
The following pattern ended up working well:
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
}
Notes:
I decided to switch the UI to a specific state like:
Waiting for I/O to complete...
And in this case, setting the interval to a not too low value such as 3000 ms is better:
FileSystemWatcher
is slow at raising events And here's a mini-table about events raised according a user's action:
User action | Callbacks raised |
---|---|
Create | Created |
Delete | Changed, Deleted |
Rename | Changed, Created, Deleted |
Move | Changed, Created, Deleted |
You may want to note that, ironically, Renamed
isn't raised at all even for a rename operation; this probably has to do with how an application renames a file, there are multiple ways to do it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.