首页 > 解决方案 > 在这种特殊情况下可能需要 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 只处理图形)

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

提前致谢。

标签: c#.netroslyn

解决方案


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

进一步解释:@canton7 写字瞬间一针见血

我认为即使最终调用了终结器,您的应用程序也不应该崩溃

根本问题以 IDisposable 的次优实现形式隐藏在第 3 方 DLL 中。一旦我放大了它,就很容易为此产生一种解决方法。

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


推荐阅读