2011-04-26 188 views
1

哪種更正確的方式來轉發COM對象,類型1或類型2或無關緊要? (_ 文件接口發佈Com對象

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; 
     } 
    } 
+0

'DisposeUnmanagedResources1()'似乎就足夠了。 – 2011-04-26 21:44:03

回答

2

演員在這裏並不做任何事情。它仍然是同一個對象。 ReleaseComObject的簽名需要一個object,所以它只會得到一個對象引用。

內部Marshall.ReleaseComObject正在減少其引用計數。如果它的引用計數爲零並且封裝將被關閉,那麼運行時將釋放本地對象。在這裏管理方面你沒有太大的影響力。

2

這裏的一般答案是:既不。 CLR負責爲你釋放COM對象;如果你絕對需要明確地控制釋放,你應該只使用Marshal.ReleaseComObject;例如。按特定順序發佈特定對象。這些往往是有些先進的情況。最正常的代碼應該讓GC完成它的工作。

另請注意,ReleaseComObject不直接映射到IUnknown :: Release() - 請查看this article from Chris Brumme on MSDN瞭解有關它如何工作以及何時使用它的更多細節。關於您希望在this Visual Studio blog article處使用ReleaseComObject的案例類型的更多背景信息。

3

正確的做法是什麼也不做 - .Net框架將負責在對象不再可達時遞減引用計數。

事實上,有幾個原因,你不應該呼叫ReleaseComObject - 首先是因爲COM對象可能實際上是一個管理的COM對象,在這種情況下,調用ReleaseComObject會失敗,其次是因爲其他受管組件可能會引用它們仍在使用的_document。 (可能在您的示例中不是,但在其他情況下很可能)

有關更多信息,請參見this blog article

更新: BrendanMcKs回答了爲什麼您可能要顯式調用在某些情況下ReleaseComObject(一般服務器應用程序),以儘快釋放COM對象的性能的原因了幾個有趣的文章。