Dot-Net

我什麼時候需要呼叫 ReleaseComObject?

  • May 7, 2012

在 Microsoft Office 外掛中,我們通過事件傳遞 COM 對象。舉一個特定的例子,當 Word 打開一個文件時,我們被呼叫並傳遞了一個 Document 對象。那麼我們什麼時候需要呼叫 Marshal.ReleaseComObject() 呢?

  1. 如果我們訪問 Document 對象,是否需要對其呼叫 release?或者我們可以假設 Word 已經訪問過它並會清理它嗎?
  2. 如果我們訪問給我們一個字元串的 Document.Name。由於字元串不是 COM 對象,我們不需要清理它——對嗎?
  3. 但是,如果我們訪問返回包裝 COM 對象的類的任何成員(這是由成員方法/函式返回的任何類),我們確實需要呼叫 release - 對嗎?

如果我們錯過了發布,會發生什麼?我們持有的任何 COM 對象的時間不確定,我們將其包裝在一個實現了 IDisposable 的類中。完成後我們呼叫 Dispose()。但是一些處理這個的程式碼很複雜,我猜我們偶爾會遇到我們不呼叫 Dispose 的情況。

我們最好有一個終結器,然後為這些對象的每個實例增加成本(很多!)?還是我們最好使用少量從未發布的 Word COM 對象?

謝謝 - 戴夫

簡而言之,您對 COM 對象的每一次引用都必須被釋放。如果不這樣做,該過程將保留在記憶體中。

不包括您未明確引用的值類型(字元串等)和子 COM 對象。

一個例外可能是作為事件參數傳遞給您的 COM 對象。我認為您不需要釋放它們,但我不確定。但是,快速測試應該可以證實這一點。(在釋放和不釋放 COM 對象的情況下嘗試您的載入項。查看載入項是否開始表現得滑稽,或者在應用程序關閉後是否有任何相關程序仍在執行。)

要解決您的具體問題:

  1. 如果我們訪問 Document 對象,是否需要對其呼叫 release?或者我們可以假設 Word 已經訪問過它並會清理它嗎?——你必須釋放它。
  2. 如果我們訪問給我們一個字元串的 Document.Name。由於字元串不是 COM 對象,我們不需要清理它——對嗎?– 你不需要清理值類型。
  3. 但是,如果我們訪問返回包裝 COM 對象的類的任何成員(這是由成員方法/函式返回的任何類),我們確實需要呼叫 release - 對嗎?– 如果你沒有明確引用它,你不需要釋放它。(有一些例外。例如,在我的這個問題中,我發現一個特定的 COM 方法正在實例化一個 COM 對象並且從不釋放它。由於我無法控制方法實現,我唯一的選擇是避免使用該方法。)
  4. 如果我們錯過了發布,會發生什麼?– 程序(winword.exe、excel.exe等)將保留在記憶體中。隨著時間的推移,所有這些未終止的程序將耗盡機器上的所有可用記憶體。
  5. 我們最好有一個終結器,然後為這些對象的每個實例增加成本(很多!)?還是我們最好使用少量從未發布的 Word COM 對象?– 你最好使用終結器。總是釋放你的 COM 對象!我發現這裡列出的步驟是最有效的。(這些步驟使用 FinalReleaseComObject,它比 ReleaseComObject 更受歡迎。)我還建議不要殺死 Office 程序作為不釋放 COM 的替代方法。隨著時間的推移,這將導致 Office 互操作出現問題(我從未完全理解)。

引用自:https://stackoverflow.com/questions/10473021