.NET运行时何时为COM对象保持引用计数> 1?

Wim*_*nen 6 .net com com-interop rcw

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

如果我没有弄错的话,上面暗示Marshal.FinalReleaseComObjectMarshal.ReleaseComObject在实践中做同样的事情.

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

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

Han*_*ant 5

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

你可以直接通过Marshal.ReleaseComObject()来修改引用计数,它会像终结器一样递减它,而Marshal.FinalReleaseComObject()将它拉到零,保证调用IUnknown :: Release()方法.他们当然属于"更清楚你正在做什么"的类别.出错会产生丑陋且不可剔除的"COM对象与其底层RCW分离"异常.