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

标签 c# .net debugging breakpoints

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

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

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

System.IO.IOException
HResult=0x80070020
Message=The process cannot access the file 'C:\ProgramData\Path\To\File.sqlite' because it is being used by another process.
Source=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() 不会改变行为。

非常感谢任何见解!

最佳答案

几个小时后,谷歌了一番,拔了好多根头发,我已经弄清楚了这个行为的原因。

根据我的发现,这个问题是由于垃圾收集没有按我们的预期完成造成的。

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

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

GC.WaitForPendingFinalizers();

关于c# - 抛出异常,除非在断点后运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56743158/

相关文章:

debugging - flutter 调试器不会在断点处停止

ios - get-task-allow 在 Xcode 中做什么?

c# - 将图片嵌入到 outlook 电子邮件正文

C# 扩展方法类型

c# - StringBuilder 类是如何实现的?每次我们附加时它是否在内部创建新的字符串对象?

c# - 使用 Json.Net 反序列化时出现错误 "Cannot deserialize the current JSON array"

.net - 关于让 Sitefinity CMS 以中等信任度工作的任何提示?

c# - 关于处理多线程事件中的异常的建议

c# - 序列化类型对象的属性

c++ - 是否可以从 Visual Studio 调试器检测 GDI 泄漏?