我使用。net 3.5,试图递归删除目录使用:
Directory.Delete(myPath, true);
我的理解是,如果文件正在使用或存在权限问题,这应该抛出,但否则它应该删除目录及其所有内容。
然而,我偶尔会遇到这样的情况:
System.IO.IOException: The directory is not empty.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
...
我并不惊讶于这个方法有时会抛出错误,但我惊讶于当递归为真时得到这个特定的消息。(我知道目录不是空的。)
是否有一个原因,我将看到这个而不是AccessViolationException?
当方法是异步的并像这样编码时,我解决了上述问题的一个可能实例:
// delete any existing update content folder for this update
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);
用这个:
bool exists = false;
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
exists = true;
// delete any existing update content folder for this update
if (exists)
await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);
结论?去除用于检查存在的句柄有一些异步的方面,微软无法与之对话。这就好像if语句中的异步方法让if语句充当using语句一样。
这个答案基于:https://stackoverflow.com/a/1703799/184528。与我的代码不同的是,我们只递归许多删除子目录和文件时,需要调用目录。第一次尝试删除失败(这可能是因为windows资源管理器查看目录)。
public static void DeleteDirectory(string dir, bool secondAttempt = false)
{
// If this is a second try, we are going to manually
// delete the files and sub-directories.
if (secondAttempt)
{
// Interrupt the current thread to allow Explorer time to release a directory handle
Thread.Sleep(0);
// Delete any files in the directory
foreach (var f in Directory.GetFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
File.Delete(f);
// Try manually recursing and deleting sub-directories
foreach (var d in Directory.GetDirectories(dir))
DeleteDirectory(d);
// Now we try to delete the current directory
Directory.Delete(dir, false);
return;
}
try
{
// First attempt: use the standard MSDN approach.
// This will throw an exception a directory is open in explorer
Directory.Delete(dir, true);
}
catch (IOException)
{
// Try again to delete the directory manually recursing.
DeleteDirectory(dir, true);
}
catch (UnauthorizedAccessException)
{
// Try again to delete the directory manually recursing.
DeleteDirectory(dir, true);
}
}
上面的答案对我都没用。似乎我自己的应用程序在目标目录上使用DirectoryInfo导致它保持锁定。
强制垃圾收集似乎解决了这个问题,但不是马上就能解决的。在需要的地方尝试删除几次。
注意目录。存在,因为它可以在异常后消失。我不知道为什么我的删除被延迟了(Windows 7 SP1)
for (int attempts = 0; attempts < 10; attempts++)
{
try
{
if (Directory.Exists(folder))
{
Directory.Delete(folder, true);
}
return;
}
catch (IOException e)
{
GC.Collect();
Thread.Sleep(1000);
}
}
throw new Exception("Failed to remove folder.");