gpt4 book ai didi

c# - 什么时候需要在 C# 中通过 COM 查询的接口(interface)上调用 Marshal.ReleaseComObject

转载 作者:可可西里 更新时间:2023-11-01 08:40:57 26 4
gpt4 key购买 nike

我一直在使用一些 DirectShow 接口(interface)来使用 C# 和 DirectShow.Net 播放数字电视 (DVB-T) .我最近遇到运行时错误 COM object that has been separated from its underlying RCW cannot be used.

此错误发生在以下行中:

_guideData = _transportInformationFilter as IGuideData;

_transportInformationFilter 属于 IBaseFilter 类型,这是一个先前通过 DirectShow.Net 实用程序函数分配的 COM 对象。

我假设错误是由于 _transportInformationFilter 以某种方式被过早释放,我将其追溯到以下方法(删除了错误处理):

private void AttachGuideDataEvent()
{
IConnectionPoint connPoint = null;
IConnectionPointContainer connPointContainer = null;
try
{
connPointContainer = _transportInformationFilter as IConnectionPointContainer;
if (connPointContainer == null) /* error */

var guideDataEventGuid = typeof (IGuideDataEvent).GUID;
connPointContainer.FindConnectionPoint(ref guideDataEventGuid, out connPoint);
if (connPoint == null) /* error */

int cookie;
connPoint.Advise(this, out cookie);
if (cookie == 0) /* error */
_persistIGuideDataEventCookie = cookie;
}
finally
{
if (connPointContainer != null)
Marshal.ReleaseComObject(connPointContainer);
if (connPoint != null)
Marshal.ReleaseComObject(connPoint);
}
}

据我所知,connPointContainer = _transportInformationFilter as IConnectionPointContainer 应该会调用 _transportInformationFilter COM 对象上的 QueryInterface,因此需要单独发布。但是,对 Marshal.ReleaseComObject(connPointContainer) 的调用是导致 _transportInformationFilter 与其 RCW 分离的罪魁祸首;删除此调用可解决问题。

鉴于此,在什么情况下我需要在 C# 中显式释放 COM 对象(使用 Marshal.ReleaseComObject)以避免泄漏资源?

最佳答案

几乎没有。 ReleaseComObject 管理 RCW 的引用计数,而不是底层对象,并且不直接类似于 IUnknown.Release。您应该让 CLR 管理它的 QueryInterfaceRelease

The RCW has a reference count that is incremented every time a COM interface pointer is mapped to it. The ReleaseComObject method decrements the reference count of an RCW. When the reference count reaches zero, the runtime releases all its references on the unmanaged COM object, and throws a System.NullReferenceException if you attempt to use the object further. If the same COM interface is passed more than one time from unmanaged to managed code, the reference count on the wrapper is incremented every time, and calling ReleaseComObject returns the number of remaining references.

...

This method enables you to force an RCW reference count release so that it occurs precisely when you want it to. However, improper use of ReleaseComObject may cause your application to fail, or may cause an access violation.

来自 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx

仅供引用,直接调用IUnknown.Release的方法是Marshal.Release ,而不是 ReleaseComObject

关于c# - 什么时候需要在 C# 中通过 COM 查询的接口(interface)上调用 Marshal.ReleaseComObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5086162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com