我的行为很奇怪。我有,
Directory.Delete(tempFolder, true);
if (Directory.Exists(tempFolder))
{
}
有时 Directory.Exists 返回 true。为什么?可能是资源管理器打开了吗?
最佳答案
Directory.Delete
调用 Windows API 函数 RemoveDirectory
.记录观察到的行为:
The
RemoveDirectory
function marks a directory for deletion on close. Therefore, the directory is not removed until the last handle to the directory is closed.
不幸的是,.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
尽管通常应该优先于事件避免轮询,但为此安装一个文件系统观察器有点过头了。不过请记住,此操作不是免费的,尤其是在处理网络驱动器时。
更新: .NET 的 Reference Source可用,执行Directory.Delete可以检查。此方法的第一个操作是遍历所有文件并删除它们。迭代是使用 FindFirstFile 实现的/FindNextFile .返回的句柄存储为 SafeFindHandle , SafeHandle 的具体子类.作为documentation指出, native 句柄是通过具体的 ReleaseHandle 释放的覆盖。从(推迟的)关键终结器调用 ReleaseHandle。由于最终确定是不确定的,这解释了打开句柄,负责延迟目录删除。
但是,此信息无助于找到比上述解决方案(轮询完成)更好的解决方案。
这个问题的其他答案没有找出核心问题,充其量只是巧合。 BanksySan's answer添加不相关的代码,引入延迟以允许有时间关闭打开的句柄。 Byeni's answer更接近,但仍然偏离:当他谈到引用目录的对象时,他几乎一针见血。但是,引用目录的对象称为句柄,这是一种 native 资源。 native 资源在终结器中处理,
GC.Collect()
不运行终结器。这似乎也可以通过购买额外的时间来实现。
关于c# - 在 Directory.Delete 之后,Directory.Exists 有时会返回 true 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24265481/