直到最近,我还认为 .NET 运行时在创建 COM 对象时只会将 COM 对象的引用计数增加 1 运行时可调用包装器, ,并且为任何给定的 COM 对象只创建一个这样的运行时可调用包装器。

如果我没记错的话,上面的意思是 Marshal.FinalReleaseComObjectMarshal.ReleaseComObject 在实践中做同样的事情。

然而,今天我正在编写一些测试来验证我的代码是否正确释放了 COM 对象。我通过调用所谓释放的对象并检查预期的来做到这一点 InvalidComObjectException. 事实证明,有些情况是在 a 之后抛出异常的 FinalReleaseComObject, ,但不是在 ReleaseComObject.

这是否意味着 .NET 2.0 运行时可以保存多个对 COM 对象的引用?如果是这样,它什么时候这样做?

有帮助吗?

解决方案

这里有一个额外的间接级别。是的,RCW 在本机 COM 接口指针上保留单个引用计数。但 RCW 也有一个引用计数,每次将 COM 接口指针映射到 RCW 时,它都会递增。如果 COM 方法返回接口指针,则可能会发生这种情况。相应 .NET 包装类的终结器将其递减。

您可以直接通过 Marshal.ReleaseComObject() 修改该引用计数,它像终结器一样将其减一,并通过 Marshal.FinalReleaseComObject() 直接将其清零,保证调用 IUnknown::Release() 方法。他们当然属于“更好地了解你在做什么”类别。出错会产生丑陋且无法调试的“COM 对象与其底层 RCW 分离”异常。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top