SSD驱动器上的奇怪目录删除行为



目录 c:\test 有 50 个左右的文件,没有子目录。

    If IO.Directory.Exists("C:test") Then
        IO.Directory.Delete("C:test", True)
    End If
    IO.Directory.CreateDirectory("C:test")
驱动器

C是英特尔的X25-M80 SSD驱动器,操作系统是Windows 7 64位,支持TRIM,Visual Studio是2008,目标框架3.5。执行上述代码时,CreateDirectory 会中断代码执行,而不会出现(可见的)异常。经过一番头痛,我发现在代码执行到达CreateDirectory时,删除尚未完成。如果我像这样修改我的代码:

    If IO.Directory.Exists("C:test") Then
        IO.Directory.Delete("C:test", True)
    End If
    Threading.Thread.Sleep(2000)
    IO.Directory.CreateDirectory("C:test")

然后一切都按预期工作。

除了明显的WTF之外,我的问题还有:

  • 不应该IO。目录.删除 无论驱动器是什么,都是阻塞函数调用
  • SSD 是否由于启用了 TRIM 支持而在删除时"作弊"?

我以前遇到过这个问题,但这不是特定于 SSD 驱动器的。 你最好先移动一下,然后删除:

if(Directory.Exists(dirpath))
{
    string temppath = dirpath + ".deleted";
    Directory.Move(dirpath, temppath);
    Directory.Delete(temppath, true);
}
Directory.Create(dirpath);

处理它的另一种方法是循环直到完成:

if(Directory.Exists(dirpath))
{
    Directory.Delete(dirpath, true);
    int limit = 100;
    while(Directory.Exists(dirpath) && limit-- > 0)
        Thread.Sleep(0);
}
Directory.Create(dirpath);

在用反射器探索System.IO.Directory之后,它看起来像.删除只是FindFirstFile,FindNextFile和RemoveDirectory Win API调用的包装器。关于 .Net 运行时对这些 API 调用的调用或 API 实现本身,没有任何线程或异步

现在,假设它在某种程度上是一个 TRIM 问题,您可以通过打开提升的命令提示符并使用 fsutil 来禁用 TRIM:

fsutil behavior set disabledeletenotify 1

要启用,请运行相同的命令,并将 0 作为参数。

若要查询,请使用查询作为命令参数:

fsutil behavior query disabledeletenotify 

是的,它与SSD驱动器无关。我遇到了同样的问题,但仅在客户端笔记本电脑上。我正在使用.NET 3.5。就我而言,该目录只有一个文件。在删除完成之前,CreateDirectory 似乎首先在内部执行。

这是一个在许多计算机上运行了三年的代码。客户换了一台新的笔记本电脑,代码对他来说总是失败。我无法在具有相同配置的开发/测试计算机上重现该场景。

我遇到了同样的问题。我最终只删除了目录@"C:test"的内容,并将新文件复制到目录中。那是我的问题:

使用 Directory.Delete() 和 Directory.CreateDirectory() 覆盖文件夹

我怀疑您在 NTFS 中发现了以前未公开的竞争条件,因为不存在足够快的驱动器来击中它。我不认为 TRIM 与它有任何关系(尽管我保留犯错的权利!

无论哪种方式,处理此问题的正确方法是将代码放入重试循环中:

int retries = 3;
while(true) {
    try {
        doTheOperation();
        break;
    } catch (Exception ex) {
        retries--;
        if (retries == 0) {
            throw;
        }
        Thread.Sleep(100);
        continue;
    }        
}

如果这确实是应用程序代码,请注意,您实际上是在尝试删除名为"est"的目录!

转义你的路径成为"c:\test"或使用@运算符@"c:\test"。

相关内容

  • 没有找到相关文章

最新更新