抛出异常,除非断点后 运行
Exception thrown, except if run after breakpoint
我在尝试删除文件时 运行 遇到了一些奇怪的行为。下面是一个快速代码示例:
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()
不会改变行为。
非常感谢任何见解!
几个小时后,一些Google,很多头发都被拔掉了,我已经弄清楚了这个行为的原因。
根据我的发现,这个问题是由于垃圾收集没有按我们预期的那样完成造成的。
我们所有的 SQLite 语句都包含在 using
中,确保调用 Dispose()
。出于某种原因,垃圾收集看起来不像 运行,并且一些文件锁仍然存在。当我们添加断点时,似乎有什么东西在幕后启动了垃圾收集。
添加以下内容足以让事情按我们的预期进行:
GC.WaitForPendingFinalizers();
我在尝试删除文件时 运行 遇到了一些奇怪的行为。下面是一个快速代码示例:
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()
不会改变行为。
非常感谢任何见解!
几个小时后,一些Google,很多头发都被拔掉了,我已经弄清楚了这个行为的原因。
根据我的发现,这个问题是由于垃圾收集没有按我们预期的那样完成造成的。
我们所有的 SQLite 语句都包含在 using
中,确保调用 Dispose()
。出于某种原因,垃圾收集看起来不像 运行,并且一些文件锁仍然存在。当我们添加断点时,似乎有什么东西在幕后启动了垃圾收集。
添加以下内容足以让事情按我们的预期进行:
GC.WaitForPendingFinalizers();