FileSystemWatcher在网络路径上失效,需重新部署恢复
网络共享文件夹FileSystemWatcher一周后失效的排查与解决
针对你遇到的FileSystemWatcher(FSW)监控网络共享文件夹一周后失效的问题,结合生产环境常见场景和你的代码,整理以下排查方向与解决方案:
常见失效原因及处理方法
1. 网络共享会话中断
网络共享依赖SMB会话维持连接,服务器可能因为超时、网络波动、共享端重启等原因断开会话,导致FSW失去监听能力。
- 解决:添加定期连接检测逻辑,比如每1-2小时尝试访问共享目录(获取目录信息或读取测试文件),一旦发现无法访问立即重启FSW;同时监听FSW的
Error事件,捕获连接相关异常时自动重启。
2. FSW内部缓冲区溢出
当共享文件夹短时间内有大量文件操作时,FSW默认的8KB内部缓冲区容易溢出,导致后续事件丢失,严重时会使Watcher静默失效。
- 解决:增大缓冲区大小(通过
InternalBufferSize设置,最大值为65536字节);同时确保事件处理逻辑高效,异步处理业务时避免长时间占用线程。
3. 权限或共享配置变更
运行FSW的服务账号可能因权限过期、共享目录权限调整等原因失去访问权限,导致FSW无法正常监听。
- 解决:定期验证账号对共享目录的读写权限;在代码中捕获权限相关异常,记录日志并尝试重启FSW。
4. 未处理的异常掩盖问题
你的代码中捕获了异常但未做任何处理,某次业务逻辑异常可能导致后续流程中断,甚至间接影响FSW运行(比如业务逻辑持有文件句柄未释放,导致目录监听异常)。
- 解决:在catch块中添加详细日志记录(包含异常信息、文件路径等),方便定位问题;确保异常不会扩散影响FSW核心监听逻辑。
5. Watcher对象被意外回收或未正确重启
如果FSW所在进程被系统回收,或者Stop方法执行后未重新实例化Watcher,复用已Dispose的对象会导致无法正常监听。
- 解决:将Watcher改为非readonly字段,重启时重新实例化;Stop方法中正确释放资源并置空对象。
优化后的代码示例
结合上述建议,调整你的代码如下:
private FileSystemWatcher _watcher; private Timer _connectionCheckTimer; public void Start() { // 先清理旧的Watcher和定时器 Stop(); _watcher = new FileSystemWatcher(); _watcher.Path = "Network Shared folder Path"; _watcher.Filter = "*.*"; _watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // 增大缓冲区到最大允许值 _watcher.InternalBufferSize = 65536; // 文件创建事件处理 _watcher.Created += async (o, e) => { try { // 异步执行业务逻辑,避免阻塞Watcher线程 await ProcessFileAsync(e.FullPath); } catch (Exception exception) { // 替换为你的日志组件,记录异常详情 Console.WriteLine($"处理文件{e.FullPath}出错: {exception.Message}\n{exception.StackTrace}"); } }; // 监听Watcher自身错误,发生时自动重启 _watcher.Error += (o, e) => { var ex = e.GetException(); Console.WriteLine($"FSW发生错误: {ex.Message}\n{ex.StackTrace}"); // 延迟5秒后重启,避免频繁重启 Task.Run(async () => { await Task.Delay(5000); Start(); }); }; _watcher.EnableRaisingEvents = true; // 启动共享连接检测定时器,每小时检测一次 _connectionCheckTimer = new Timer(_ => CheckSharedConnection(), null, 0, 3600000); } public void Stop() { // 停止定时器 _connectionCheckTimer?.Dispose(); _connectionCheckTimer = null; // 释放Watcher资源 if (_watcher != null) { _watcher.EnableRaisingEvents = false; _watcher.Dispose(); _watcher = null; } } private async Task ProcessFileAsync(string filePath) { // 你的业务逻辑实现 await Task.CompletedTask; } private void CheckSharedConnection() { try { var dirInfo = new DirectoryInfo(_watcher?.Path ?? string.Empty); if (!dirInfo.Exists) { Console.WriteLine("共享目录不可访问,重启FSW"); Start(); } } catch (Exception ex) { Console.WriteLine($"检测共享连接失败: {ex.Message},重启FSW"); Start(); } }
内容的提问来源于stack exchange,提问作者Bhargav
相关产品推荐
相关产品推荐

