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()不会改变行为。
任何见解都将不胜感激!
经过几个小时的谷歌和拔毛,我已经弄清楚了这种行为的原因。
据我发现,此问题是由于垃圾收集未按我们预期完成而引起的。
我们所有的 SQLite 语句都包含在using, 确保Dispose()被调用。由于某种原因,垃圾收集似乎没有运行,并且仍然存在一些文件锁。当我们添加断点时,看起来好像有一些东西在幕后启动了垃圾收集。
添加以下内容足以让事情按我们的预期工作:
GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |