【问题标题】:Is it necessary to call Marshal.ReleaseComObject in C#4 when doing COM?做COM时是否需要在C#4中调用Marshal.ReleaseComObject?
【发布时间】:2011-07-06 21:07:36
【问题描述】:

我有 VS2010,并在我的项目中添加了对 COM 库的引用,并且 VS 在项目中嵌入了主互操作。

如果我从 COM 库中引用对象并且我想在不等待 GC 的情况下快速处理它们,是否需要调用 ReleaseComObject ?

【问题讨论】:

  • 将所有 COM 对象引用设置为 null 并调用 GC.Collect() 更可靠。

标签: com c#-4.0


【解决方案1】:

Marshal.ReleaseComObject 提供了一种方法,可以立即从托管代码中正在使用它的任何地方删除对这个 COM 对象的引用(因为它从持有它的 RCW 释放底层 IUnknown)。

正如 Hans 所指出的,通常正确的做法是简单地将对象设为空,以允许 CLR 和 GC 在适当的时间进行 COM 对象销毁。

但是,在您需要立即采取行动的情况下(COM 对象拥有昂贵/稀缺的资源,或者可能在关闭期间排序非常复杂),调用 ReleaseComObject 可能是正确的做法。

马丁

【讨论】:

  • 所以,在我的情况下,因为我需要释放昂贵的资源,那么我真的应该调用 ReleaseComObject 然后将 .net 变量设置为 null ?
  • 是的,如果您确实需要及时释放该资源。只有当这个问题显示为性能问题时,我才会这样做。另外:首先将 .net 变量设置为 null。
  • 嗯...如果我将变量设置为 null 那么我不能在 ReleaseComObject 中使用它了...
  • 您将成员变量设置为 Null,将其移动到局部变量,在其上使用 ReleaseComObject,并将其也设为 null。
【解决方案2】:

在清理内存方面有两种方法。

  • 引用计数算法
  • 垃圾回收

COM 组件使用引用计数算法来回收内存。每当您不需要 com 组件的引用时,您都可以调用它。但通常我的方法是创建一个虚拟堆栈并删除下面的 C# 中的源代码之类的引用。只要 RCW 存在,.NET 就保证 COM 组件存在。当 RCW 被垃圾回收时,释放方法被调用。无需在代码中调用 release。但它不会影响 gc 循环。

void DoSth
{
       {
            RunTimeCallableWrapper area for the code
            ReleaseComObject
       }  
 }

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 2016-11-09
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多