Directory.Delete执行报错:远程服务器文件被占用,二次执行失败求解决
这个问题我之前也遇到过类似的,结合你的代码和报错信息,给你几个针对性的解决思路:
先检查
NetworkShareAccesser的Dispose实现
你用了using块来自动释放NetworkShareAccesser,但如果这个类的Dispose方法没有彻底关闭远程共享连接(比如没调用WNetCancelConnection2这类底层API释放会话),第二次执行时可能残留的连接还在占用目录资源。得确保Dispose里不仅释放本地资源,还正确取消了和远程服务器的共享会话。给删除操作加延迟重试逻辑
远程文件系统的操作经常有延迟,第一次复制完文件后,远程服务器的索引服务、杀毒软件可能还在扫描这些文件,导致第二次立即删除时被锁定。可以给Directory.Delete加个重试机制,比如重试3次,每次间隔1秒:int retryAttempts = 3; while (retryAttempts > 0) { try { Directory.Delete(absolutePathServerForService, true); break; } catch (IOException ex) { retryAttempts--; loggingService.Warn($"删除目录失败,重试剩余次数:{retryAttempts},错误信息:{ex.Message}"); System.Threading.Thread.Sleep(1000); if (retryAttempts == 0) throw; } }确保复制操作后没有残留的未释放资源
你的CopyFilesRecursively方法用了FileInfo.CopyTo,虽然是同步方法,但有时候远程网络的延迟可能导致文件句柄没有及时释放。可以在复制完成后,显式刷新目标目录:// 在CopyFilesRecursively调用后添加 var targetDir = new DirectoryInfo(targetPath); targetDir.Refresh();另外,也可以检查下
NetworkShareAccesser内部有没有打开的文件流没关闭,这也是常见的句柄泄漏原因。排查远程服务器上的占用进程
如果重试还是没用,建议在报错时,登录到远程服务器上用工具排查哪个进程在占用目标目录。比如用微软的handle.exe(Sysinternals工具集里的),执行handle.exe <目录路径>,就能看到占用的进程ID和名称。通常可能是Windows Search服务、防病毒软件,或者其他正在访问该目录的应用,找到后可以针对性地调整这些服务的配置。换用更可靠的删除方式
.NET自带的Directory.Delete在处理远程目录时偶尔会有兼容性问题,你可以试试用Windows命令行的rmdir工具来删除:var deleteProcess = new System.Diagnostics.ProcessStartInfo { FileName = "cmd.exe", Arguments = $"/c rmdir /s /q \"{absolutePathServerForService}\"", WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true }; using (var process = System.Diagnostics.Process.Start(deleteProcess)) { process.WaitForExit(); if (process.ExitCode != 0) { string error = process.StandardError.ReadToEnd(); loggingService.Error($"命令行删除目录失败:{error}"); throw new IOException($"删除目录失败,错误信息:{error}"); } }这种方式会调用系统底层的删除逻辑,有时候比
.NET的方法更稳定。
内容的提问来源于stack exchange,提问作者Alex




