释放Com对象

时间:2011-04-26 21:41:53

标签: c# com interop release

哪种更正确的方法来释放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;
        }
    }

3 个答案:

答案 0 :(得分:3)

正确的做法是什么都不做 - 当对象不再可达时,.Net框架将负责减少引用计数。

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

有关详细信息,请参阅this blog article

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

答案 1 :(得分:2)

演员在这里没有做任何事情。它仍然是同一个对象。 ReleaseComObject的签名需要object,因此它无论如何都会得到一个对象引用。

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

答案 2 :(得分:2)

这里的一般答案是:两者都没有。 CLR负责为您释放COM对象;你应该只使用Marshal.ReleaseComObject,如果你绝对需要明确控制释放;例如。以特定顺序释放特定对象。这些往往是一些先进的案例。大多数普通代码应该让GC做它的事情。

另请注意,ReleaseComObject不会直接映射到IUnknown :: Release() - 请查看this article from Chris Brumme on MSDN以获取有关其工作原理以及何时使用它的更多详细信息。有关您希望在this Visual Studio blog article使用ReleaseComObject的案例类型的更多背景知识。