C# 调试期间是否运行垃圾收集?

C# 调试期间是否运行垃圾收集?,c#,garbage-collection,C#,Garbage Collection,我有一个程序,可以打开一个Excel COM对象,做一些事情,然后关闭它。然后我想在文件关闭后移动它。如果我在没有断点的情况下运行该程序,则效果很好。但是,如果我在尝试移动文件之前进入调试模式,我会得到一个IOException:“该进程无法访问该文件,因为它正被另一个进程使用。” 那怎么办?允许程序全速运行时垃圾收集的性能是否比我单步执行时更好?单步执行我的代码不仅仅是非常缓慢地运行它吗?调试模式还有其他后果吗?仅因为我正在调试且未运行exe而遇到的其他错误?垃圾收集在未在调试器中运行时会进行

我有一个程序,可以打开一个Excel COM对象,做一些事情,然后关闭它。然后我想在文件关闭后移动它。如果我在没有断点的情况下运行该程序,则效果很好。但是,如果我在尝试移动文件之前进入调试模式,我会得到一个IOException:“该进程无法访问该文件,因为它正被另一个进程使用。”


那怎么办?允许程序全速运行时垃圾收集的性能是否比我单步执行时更好?单步执行我的代码不仅仅是非常缓慢地运行它吗?调试模式还有其他后果吗?仅因为我正在调试且未运行exe而遇到的其他错误?

垃圾收集在未在调试器中运行时会进行不同的优化,是的。特别是,CLR可以检测到一个变量将不再用于方法的其余部分,并不再将其视为GC根。在调试器中,作用域中的变量在整个方法中充当GC根,因此您仍然可以使用调试器检查值


然而,这应该很少是一个问题——只有当终结器确实执行了一些清理时,它才会影响事情,并且如果您及时明确地整理事情(例如使用
语句),您通常不会注意到差异。

作为记录,我也遇到过几次这种情况。我发现,在调试模式下测试终结器调用本机端代码时,这是可行的:

((Action)()=>{
   // Do your stuff in here ...
})();

GC.Collect();
GC.WaitForPendingFinalizers();

垃圾收集器似乎在本地方法作用域内保留根目录下的分配副本,因此通过创建新的方法作用域并退出,GC通常会释放资源。到目前为止,这对于我的调试来说效果很好。

所以我可以期望我的程序在不在调试器中运行时运行得更快?调试器故意占用更多内存…所以我可以调试。正确的?无论哪种方式,我都不明白为什么断点的位置会影响对象是否可用。如果我点击F5,用零断点测试我的代码,并且从不“介入”,那么调试器的性能是否仍然与常规构建不同?@Brad:“快得多”是相当主观的。老实说,现在还不清楚你在做什么——但是用F5运行仍然在使用调试器;Ctrl-F5不起作用。这不是你运行哪个构建的问题,而是你如何运行它。(您可以在调试器中运行发布版本,也可以在调试器中运行调试版本。)因此,如果我在调试器中运行调试版本,像debug.Print()这样的行还会被执行吗?在发布版本中它们被忽略了吗?您如何处理Excel对象的处理?如果在VS调试器停止后看到错误,并且让代码运行COM对象处理,则可能有一个有效点。