引发异常,除非在断点后运行

时间:2019-06-24 19:57:53

标签: c# .net debugging breakpoints

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

if (File.Exists(filePath))
{
    File.Delete(filePath);
}

奇怪的行为是尝试删除文件时抛出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);
    }

没有引发异常。

如果我们这样添加断点:

    Console.WriteLine("Break");
    if (File.Exists(filePath))
    {
<x>     File.Delete(filePath);
    }

或类似这样:

    Console.WriteLine("Break");
<x> if (File.Exists(filePath))
    {
        File.Delete(filePath);
    }

引发异常。

除了更改断点之外,所有操作均完全相同。我们可以可靠地重现此行为。我已经对此行为进行了一些研究,但找不到任何适用的方法。我很好奇这个行为是否记录在任何地方,或者是否缺少任何明显的东西。

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

任何见识都将受到赞赏!

1 个答案:

答案 0 :(得分:1)

几个小时后,一些谷歌和许多头发拔了出来,我已经弄清了这种现象的原因。

从我发现的情况来看,此问题是由于垃圾收集未按预期完成所致。

我们所有的SQLite语句都包装在using中,以确保调用Dispose()。由于某种原因,它看起来好像没有在运行垃圾回收,并且保留了一些文件锁。当我们添加断点时,似乎在后台启动了“垃圾回收”。

添加以下内容足以使我们按预期工作:

GC.WaitForPendingFinalizers();
相关问题