GC.Collect() 在这种特殊情况下是否有必要?

Might GC.Collect() be warranted in this particular case?

免责声明:是的,我知道关于是否使用 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 仅处理图形)

我完全知道这是一个相当模糊的问题描述,源代码很少。这是因为该应用程序包含大量源代码,我不知道这里可能有哪些相关内容。另外,上面文本中的所有命名空间都是指 Microsoft.CodeAnalysis.CSharp.Scripting,除了 VISA 是自定义的。显然,我很乐意回答任何后续问题以弄清这个问题。

提前致谢。

简短回答:不。这不仅没有根据,而且完全忽略了实际问题。

进一步说明:@canton7写的瞬间一针见血

I'd argue that your application shouldn't crash even if a finalizer does end up being called

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

我原来的问题被误导了,所以我想说一下我 应该 提出的问题: 当我的应用程序的日志记录没有显示任何内容时,如何跟踪我的 C# 应用程序的崩溃? 这个问题已经在很多帖子中得到了全面的回答。就我而言,崩溃可以在 Windows 事件日志中看到。