抛出异常,除非在断点后运行

Jac*_*sey 5 .net c# debugging breakpoints

尝试删除文件时,我遇到了一些奇怪的行为。下面是一个快速代码示例:

if (File.Exists(filePath))
{
    File.Delete(filePath);
}
Run Code Online (Sandbox Code Playgroud)

奇怪的行为是尝试删除文件时抛出 System.IO.IOException:

System.IO.IOException
HResult=0x80070020
Message=进程无法访问文件“C:\ProgramData\Path\To\File.sqlite”,因为该文件正被另一个进程使用。
来源=mscorlib

在我们的应用程序中,我们仅在 using 语句中访问文件,以避免任何持久保留。该文件是一个 sqlite 数据库,没有持久或打开的连接。

这似乎是一个很正常的问题。当向代码添加断点时,奇怪的行为就开始了。例如,如果我们在上面添加 Console.WriteLine 语句,则在该语句上中断,然后继续:

<x> Console.WriteLine("Break");
    if (File.Exists(filePath))
    {
        File.Delete(filePath);
    }
Run Code Online (Sandbox Code Playgroud)

没有抛出异常。

如果我们像这样添加断点:

    Console.WriteLine("Break");
    if (File.Exists(filePath))
    {
<x>     File.Delete(filePath);
    }
Run Code Online (Sandbox Code Playgroud)

或者像这样:

    Console.WriteLine("Break");
<x> if (File.Exists(filePath))
    {
        File.Delete(filePath);
    }
Run Code Online (Sandbox Code Playgroud)

抛出异常。

除了更改断点之外,一切都运行得完全相同。我们可以可靠地重现这种行为。我对这种行为进行了一些研究,但找不到任何适用的内容。我很好奇这种行为是否在任何地方都有记录,或者我是否遗漏了任何明显的东西。

编辑:我忘记添加一些注释,我们可以在多台不同的机器上重现此行为。添加 aThread.Sleep()不会改变行为。

任何见解都将不胜感激!

Jac*_*sey 0

经过几个小时的谷歌和拔毛,我已经弄清楚了这种行为的原因。

据我发现,此问题是由于垃圾收集未按我们预期完成而引起的。

我们所有的 SQLite 语句都包含在using, 确保Dispose()被调用。由于某种原因,垃圾收集似乎没有运行,并且仍然存在一些文件锁。当我们添加断点时,看起来好像有一些东西在幕后启动了垃圾收集。

添加以下内容足以让事情按我们的预期工作:

GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)