FileSystemWatcher Deleted事件仅偶尔触发,测试30次仅10-15次生效求助
解决FileSystemWatcher Deleted事件触发不稳定的问题
我之前也碰到过FileSystemWatcher事件触发不规律的情况,结合你近30次测试只有10-15次触发的现象,主要是几个容易忽略的细节导致的,咱们一步步解决:
1. 确保FileSystemWatcher对象不被垃圾回收
如果你的fileSystemWatcher是局部变量(比如在某个方法内部声明),方法执行完毕后,.NET的垃圾回收器可能会把它回收掉,导致后续的文件操作无法触发事件。
解决方法:把fileSystemWatcher声明为类级别的字段,保持强引用:
// 类级别字段,避免被GC回收 private FileSystemWatcher _fileSystemWatcher; public void SetupWatcher() { string fileToWatchFor = "file.txt"; var inputedFileInfo = new FileInfo(fileToWatchFor); _fileSystemWatcher = new FileSystemWatcher(inputedFileInfo.DirectoryName); _fileSystemWatcher.Filter = "*.txt"; _fileSystemWatcher.Deleted += (sender, eventArgs) => { Console.WriteLine("I was invoked when your file was deleted!"); }; // 其他配置... }
2. 必须启用事件触发
FileSystemWatcher默认是关闭事件触发的,你需要手动设置EnableRaisingEvents = true,否则无论怎么操作文件,事件都不会被触发。这是最容易漏掉的一步!
添加这行代码:
_fileSystemWatcher.EnableRaisingEvents = true;
3. 增大内部缓冲区避免溢出
当短时间内有大量文件操作(或者你的测试操作太频繁),FileSystemWatcher的内部缓冲区可能会溢出,导致部分事件丢失。默认缓冲区大小比较小,你可以适当调大(最大支持64KB):
// 设置缓冲区为64KB(最大值) _fileSystemWatcher.InternalBufferSize = 65536;
4. 额外:监听Renamed事件辅助判断
有些程序删除文件的逻辑是先重命名再删除,这种情况下Deleted事件可能不会触发,但Renamed事件会捕捉到。你可以同时监听Renamed事件,做补充判断:
_fileSystemWatcher.Renamed += (sender, eventArgs) => { // 可以判断是否是目标文件被重命名后删除的情况 if (eventArgs.OldName == "file.txt") { Console.WriteLine("Target file was renamed (might be deleted afterwards)!"); } };
修正后的完整示例代码
using System; using System.IO; public class FileWatcherExample { private FileSystemWatcher _fileSystemWatcher; public void StartWatching() { string fileToWatchFor = "file.txt"; var inputedFileInfo = new FileInfo(fileToWatchFor); if (!inputedFileInfo.Directory.Exists) { Console.WriteLine("Target directory does not exist!"); return; } _fileSystemWatcher = new FileSystemWatcher(inputedFileInfo.DirectoryName) { Filter = "*.txt", InternalBufferSize = 65536, EnableRaisingEvents = true }; _fileSystemWatcher.Deleted += (sender, eventArgs) => { Console.WriteLine($"I was invoked when {eventArgs.Name} was deleted!"); }; _fileSystemWatcher.Renamed += (sender, eventArgs) => { if (eventArgs.OldName.Equals(fileToWatchFor, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine($"Target file {fileToWatchFor} was renamed to {eventArgs.Name}"); } }; Console.WriteLine("Watching for .txt file deletions... Press any key to stop."); Console.ReadKey(); // 停止监听并释放资源 _fileSystemWatcher.EnableRaisingEvents = false; _fileSystemWatcher.Dispose(); } }
按照这个配置再测试,应该能大幅提升Deleted事件的触发成功率,基本可以做到每次删除都能捕捉到。
内容的提问来源于stack exchange,提问作者perepelart
相关产品推荐
相关产品推荐

