释放Com对象

本文关键字:对象 Com 释放 | 更新日期: 2023-09-27 17:53:42

哪一种释放com对象的方式更正确,类型1还是类型2或者无关紧要?文档(_ 界面)

    private IHTMLDocument2 _document;

    public HtmlDocument()
    {
        _document = new HTMLDocumentClass();
    }
    private void DisposeUnmanagedResources1()
    {
        if (_document != null)
        {
            Marshal.ReleaseComObject(_document);
            _document = null;
        }
    }
    private void DisposeUnmanagedResources2()
    {
        if (_document != null)
        {
            var doc = ((HTMLDocumentClass) _document);
            Marshal.ReleaseComObject(doc);
            doc = null;
            _document = null;
        }
    }

释放Com对象

正确的做法是什么都不做 - . net框架会在对象无法访问时减少引用计数。

实际上有几个原因为什么你不应该调用ReleaseComObject -首先因为COM对象实际上可能是一个托管COM对象,在这种情况下,对ReleaseComObject的调用将失败,其次因为其他托管组件可能有对_document的引用,它们仍在使用。(可能不在您的示例中,但在其他情况下很有可能)

更多信息请看这篇博客文章。

更新: BrendanMcKs的回答有几篇有趣的文章,关于为什么您可能希望在某些情况下(通常是服务器应用程序)为了性能原因尽快释放COM对象而显式调用ReleaseComObject

cast在这里没有做任何事情。它还是原来的物体。ReleaseComObject的签名采用object,所以无论如何它都会得到一个对象引用。

内部Marshall.ReleaseComObject只是减少它的引用计数。如果本机对象的refcount为零,则运行时将释放本机对象,并且包装器将被终止。在管理方面,你没有太大的影响力。

一般的答案是:两者都不是。CLR负责为你释放COM对象;你应该只使用Marshal。ReleaseComObject如果你绝对需要显式控制释放;如。以特定的顺序释放特定的对象。这些都是比较严重的病例。大多数正常的代码应该让GC做它自己的事情。

还需要注意的是,ReleaseComObject并没有直接映射到IUnknown::Release() -查看chrisbrumme在MSDN上的这篇文章,了解更多关于它是如何工作的以及何时使用它的详细信息。在Visual Studio博客文章.

中有更多关于您想要使用ReleaseComObject的情况的背景知识。