FileSystemWatcher监视含文件文件夹删除时未触发Error事件的问题
FileSystemWatcher Error Event: Why Empty vs Non-Empty Folder Deletion Behaves Differently
I've run into this exact quirk with FileSystemWatcher before, and it all comes down to how Windows handles file system notifications and the watcher's internal state. Let's break down what's going on:
Observed Behavior
- When deleting a watched empty folder: The
Errorevent fires with an "Access Denied" exception. - When deleting a watched non-empty folder (e.g., containing a text file): The
Errorevent does not fire. Instead, you'll seeDeletedevents for the files inside first, followed by aDeletedevent for the folder itself.
Test Reproduction Code
Here's the console app used to verify this behavior:
class Program { static WatcherTests tests; static void Main(string[] args) { InitialiseWatcher(); Console.ReadLine(); } private static void InitialiseWatcher() { tests = new WatcherTests(); tests.InitialiseWatcher(); } } class WatcherTests { FileSystemWatcher _watcher; internal void InitialiseWatcher() { _watcher = new FileSystemWatcher(); _watcher.Changed += OnWatcher_Changed; _watcher.Created += OnWatcher_Created; _watcher.Deleted += OnWatcher_Deleted; _watcher.Error += OnWatcher_Error; _watcher.IncludeSubdirectories = false; _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite; _watcher.Path = @"c:\temp\testwatcher"; _watcher.EnableRaisingEvents = true; } private void OnWatcher_Error(object sender, ErrorEventArgs e) { Console.WriteLine($"Watcher_Error {e.GetException().Message}"); } private void OnWatcher_Deleted(object sender, FileSystemEventArgs e) { Console.WriteLine($"Watcher_Deleted {e.Name}"); } private void OnWatcher_Created(object sender, FileSystemEventArgs e) { Console.WriteLine($"Watcher_Created {e.Name}"); } private void OnWatcher_Changed(object sender, FileSystemEventArgs e) { Console.WriteLine($"Watcher_Changed {e.Name}"); } }
Why This Happens
This is a behavior of the Windows file system notification API that FileSystemWatcher wraps:
- Empty Folder Deletion: When you delete an empty folder, the watcher loses its direct target immediately. The system attempts to notify the watcher, but since the path no longer exists, the watcher throws an "Access Denied" error when trying to validate its watch context.
- Non-Empty Folder Deletion: Windows first deletes all files inside the folder, which triggers
Deletedevents for each file. Once the folder is empty and then deleted, the watcher has already processed the removal of all child items. The system sends aDeletedevent for the folder itself instead of an error, as the watcher's internal state has already been updated from the file deletions.
Consistent Handling Tips
If you need to detect when the watched folder is deleted regardless of its state:
- Listen to both the
Deletedevent (check ife.FullPathmatches your watched folder path) and theErrorevent. - In the
Errorevent, treat the "Access Denied" exception as an indicator that the folder was deleted, and optionally re-initialize the watcher if you want to monitor the path if it gets recreated later.
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

