FileSystemWatcher运行一段时间后停止触发事件的排查求助
解决FileSystemWatcher实例运行一段时间后停止触发事件的建议
以下是你可能遗漏的关键配置和处理逻辑:
保持Watcher实例的强引用
你当前在foreach循环中创建的subdirectoryWatcher是局部变量,循环结束后没有被全局容器持有,很容易被.NET垃圾回收器回收,导致后续事件无法触发。
解决方法:定义一个全局的集合(比如private List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>();),在创建每个Watcher后将其添加到集合中:// 全局集合 private List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>(); // 在循环中添加 foreach (string subdirectory in subdirectoriesToWatch) { string subdirectoryPath = Path.Combine(rootDirectory, subdirectory); FileSystemWatcher subdirectoryWatcher = CreateWatcher(subdirectoryPath, true); subdirectoryWatcher.Created += (sender, e) => { Console.WriteLine($"File created in {subdirectory}: {e.Name}"); }; _watchers.Add(subdirectoryWatcher); // 加入集合保持引用 }处理事件中的异常
FileSystemWatcher的事件处理线程如果抛出未捕获的异常,会导致该Watcher后续不再触发任何事件。必须在事件处理逻辑中添加try-catch块:subdirectoryWatcher.Created += (sender, e) => { try { Console.WriteLine($"File created in {subdirectory}: {e.Name}"); // 其他业务逻辑 } catch (Exception ex) { Console.WriteLine($"处理文件创建事件出错: {ex.Message}"); // 可选:记录日志 } };监听Error事件并处理异常情况
启用Watcher的Error事件监听,捕获缓冲区溢出、权限变更、目录不可访问等错误,必要时重新初始化Watcher:subdirectoryWatcher.Error += (sender, e) => { Console.WriteLine($"Watcher出错: {e.GetException().Message}"); // 可选:重启当前Watcher var watcher = sender as FileSystemWatcher; if (watcher != null) { watcher.EnableRaisingEvents = false; watcher.EnableRaisingEvents = true; // 或者重新创建实例 } };确认EnableRaisingEvents的状态
检查CreateWatcher方法是否正确设置了EnableRaisingEvents = true,如果该属性被意外设置为false,Watcher会停止触发事件。同时,在处理Error事件后可以重新启用该属性。避免事件处理逻辑阻塞
如果事件处理逻辑耗时较长,会导致Watcher的缓冲区无法及时处理新的文件操作,最终引发缓冲区溢出。建议将耗时的业务逻辑放到异步线程中处理:subdirectoryWatcher.Created += async (sender, e) => { try { await Task.Run(() => { // 耗时的业务逻辑 Console.WriteLine($"File created in {subdirectory}: {e.Name}"); }); } catch (Exception ex) { Console.WriteLine($"处理出错: {ex.Message}"); } };
内容的提问来源于stack exchange,提问作者tejas_12
相关产品推荐
相关产品推荐

