在这种特殊情况下,GC.Collect()是否有正当理由



免责声明:是的,我知道是否使用GC.Collect()的一般答案是一个响亮的"不&";。这是我编程几年来第一次考虑使用它。

那么,情况是这样的:我们已经开发了一个基于Microsoft.CodeAnalysis.CSharp.Scripting libraries(v3.6.0)的C#脚本工具。它是一个带有编辑器等的Winform GUI,与其他工具没有什么不同。我们将其用于集成电路的验证,这意味着它的主要任务是连接实验室设备,如电源、模式发生器、仪表等。对于与上述文书的沟通,我们主要依赖National Instrument的VISA框架,尽管并非唯一。一些设备是通过各自制造商的DLL直接控制的。总的来说,这个系统运行得很好,现在很多设计工程师都成功地使用了它,他们对.NET和C#的复杂性一无所知。

在这一点上,我应该解释一下,用户可以简单地编写一个方法(即在"顶级"上),然后执行它。这背后的Roslyn部分是将输入提供给CSharpScript.Create(),然后进行编译。方法的执行是通过Script.ContinueWith("method name")来完成的。在这种方法中,用户可以构造一个对象,比如new VISA("connection string"),它连接到设备,然后通过这个对象与设备通信。没有任何东西迫使他或她关心处理对象(即关闭连接)。

现在,问题是:最近,GUI应用程序发生了非常偶发的崩溃,系统根本没有反馈-表单刚刚关闭,仅此而已。通过反复试验,我们目前99%确信,如果所有连接对象都在一个方法中显式处理,则不会发生崩溃。因此,将方法重写为这样的方法可以解决问题:

using(var device = new VISA("connection string"))
{
device.Query("IDN?");
}

我之所以关注GC的方向,是因为与用户的任何操作都没有明显的相关性。这些人可能会毫无问题地运行这样的方法一个小时,然后,当在编辑器中滚动时,当当前没有执行任何方法时,GUI会关闭而不发表评论。这就是为什么我想从更了解Roslyn和GC的人那里得到一些意见:

  1. 这个脚本库和GC是否存在已知问题?(我认为没有)
  2. 既然明确处理对象似乎可以防止这个问题,那么这可能是GC.Collect()可能被保证使用的极为罕见的情况之一吗?(无可否认,由于家庭办公,我还无法测试这是否也能防止问题的发生)
  3. 有什么想法可以导致.NET应用程序在没有任何反馈的情况下崩溃,以及如何获得有关这种崩溃的更多信息吗?(脚本引擎是一个单独的DLL,设备驱动程序也是如此;GUI只处理图形)

我完全意识到这是对问题的一个相当模糊的描述,源代码很少。这是因为该应用程序包含相当多的源代码,我不知道这里可能有什么相关内容。此外,除了自定义的VISA之外,上述文本中的所有名称空间都引用了Microsoft.CodeAnalysis.CSharp.Scripting。显然,我很乐意回答任何后续问题,以便弄清真相。

提前谢谢。

简短回答:不。这不仅没有保证,而且完全没有实际问题。

进一步解释:@conton7在写时一针见血

我认为即使终结器最终被称为,你的应用程序也不应该崩溃

根问题隐藏在第三方DLL中,其形式至少是IDisposable的次优实现。一旦我放大了这一点,就很容易找到解决方法。

我最初的问题被误导了,我想说明我应该问的问题:当应用程序的日志记录没有显示任何内容时,如何跟踪C#应用程序的崩溃这个问题已经在许多帖子中得到了全面的回答。在我的情况下,崩溃可以在Windows事件日志中看到。

最新更新