在Directory.Delete Directory.Exists有时返回true?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Directory.Delete Directory.Exists有时返回true?相关的知识,希望对你有一定的参考价值。
我有非常奇怪的行为。我有,
Directory.Delete(tempFolder, true);
if (Directory.Exists(tempFolder))
{
}
有时Directory.Exists返回true。为什么?可能是探险家是开放的吗?
Directory.Delete
调用Windows API函数RemoveDirectory
。观察到的行为记录在案:
RemoveDirectory
函数在关闭时标记要删除的目录。因此,在关闭目录的最后一个句柄之前,不会删除该目录。
遗憾的是,.NET文档遗漏了这些信息。是否记录了静态Directory.Delete
方法是否打开目录句柄。同样,如果确实如此,则在手柄关闭时不会记录。
没有任何这些信息,您可以做的最好是轮询完成:
Directory.Delete(tempFolder, true);
while (Directory.Exists(tempFolder)) Thread.Sleep(0);
// At this point the directory has been removed from the filesystem
尽管通常应该优先考虑轮询而不是事件,但是安装文件系统观察器对于这一点来说有点过头了。但请记住,此操作不是免费的,特别是在处理网络驱动器时。
Update: With .NET's Reference Source available, the implementation of Directory.Delete can be inspected. The first action of this method is to iterate over all files and delete them. The iteration is implemented using FindFirstFile/FindNextFile. The returned handle is stored as a SafeFindHandle, a concrete subclass of SafeHandle. As the documentation points out, the native handle is freed through a concrete ReleaseHandle override. ReleaseHandle is called from a (postponed) critical finalizer. Since finalization is non-deterministic, this explains the open handle, responsible for the delayed directory delete.
但是,这些信息无助于找到比上述解决方案更好的解决方案(轮询完成)。
Other answers to this question did not identify the core issue, and work by coincidence at best. BanksySan's answer adds unrelated code that introduces a delay to allow time for open handles to be closed. Byeni's answer is closer, yet still off: When he talks about the object referencing the directory he almost nails it. However, the object referencing the directory is called a handle, a native resource. Native resources are disposed of in finalizers, and
GC.Collect()
does not run finalizers. This, too, appears to work by buying extra time.
请改用DirectoryInfo
,然后调用Refresh()
。
var dir = new DirectoryInfo(tempFolder);
dir.Delete();
dir.Refresh();
因为我们在目录上执行许多操作,所以使用DirectoryInfo
而不是Directory
更高效。这可能解释了为什么静态类上没有Refresh()
,它意味着一次性操作,因此永远不需要刷新。
以上是关于在Directory.Delete Directory.Exists有时返回true?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我使用 directory.delete 时 gif 文件不会删除?
无法使用 Directory.Delete(path, true) 删除目录
为啥 System.IO.Directory.Delete(string,bool) 仅在 asp.net 站点模拟用户时将文件夹标记为已删除