c# - 在 Directory.Delete 之后,Directory.Exists 有时会返回 true 吗?

标签 c# .net io

我的行为很奇怪。我有,

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/

相关文章:

io - Perl6 (Rakudo) - 如何处理文件中的特殊字符?

android - 输入流 I/O 上的 EBADF(错误文件编号)

django - 如何处理 mod_wsgi/django 中的阻塞 IO?

c# - 拉伸(stretch)不适用于 WPF 模板化按钮

c# - 如何在字符串列表中添加额外的字符?

c# - 从 Windows Phone 7 应用程序更改电话设置

.net - 如何从 WinForms 应用程序中用户控件上的子控件中获取事件?

c# - 如何从 C# 中的智能卡读取名称和地址等基本数据?

c# - 如何比较 dotnetrdf 中的简单文字和类型文字?

.net - 用于为 Windows Vista/7 开发 .NET 应用程序的资源?