2010-11-13 92 views
3

我從Excel中定義的C#DLL中的VBA腳本實例化COM對象。我實例化的C#類有一個執行垃圾回收的終結器,特別是它引用的其他MS Office對象,我應該看到它出現並消失在任務管理器中。實際上,單元測試表明Office進程在調用dll時出現,並在完成時消失。COM對象清理

當從VBA調用dll時,我注意到在VBA函數結束之後進程保持打開狀態,即在調用之後對象不清除,這導致我相信VBA不會釋放COM對象。

我的功能看起來是這樣的:

Function Raz(inp As String) 
Dim o: Set o = CreateObject("foo.bar") 
o.InputFields.FirstInput = inp 
o.Update 
Raz = o.OutputFields.FirstOutput 
End Function 

我已經添加了以下行,以便在函數的末尾來解決問題:在

set o = Nothing 

然而,資源我在執行和完成我的VBA腳本後,COM進程仍然保留。如何從VBA中收集我的COM對象而無需手動創建處置調用?

回答

1

在VBA命令釋放對象是

Set o = Nothing 
+0

所以我試過了,終結者仍然沒有被調用。我最終實現了IDisposable和手動配置資源,並結合set o = Nothing行......我不知道是否所有的東西都被釋放了,但至少這個配置釋放了大事情。 – tbischel 2010-11-15 21:21:07

+0

您能否介紹一下如何實現IDisposable的更多解釋?我用我編寫的Visual Foxpro 9 COM服務器也有同樣的問題。謝謝。 – Caltor 2011-09-07 10:55:43

+0

@Caltor,你需要'@tbischel'來引起他的注意(只有第一個@可以工作,所以你仍然需要自己去做)。 – 2011-09-07 14:14:37

4

COM將保留進程內存的要求,而最後一個引用消失後,萬一你想創建不久需要相同進程中的另一個對象之後。

該理論認爲,創作的過程是非常緩慢和昂貴,你可能不經意間寫一個循環或東西做這個:

While 1=1 

     Set a = CreateObject(...) 
     ' Later 
     Set a = Nothing 

Wend 

你不會想在周圍不斷地屠殺和啓動進程的Windows顛簸循環。

最終他們離開了。

1

你有弱引用到創建的對象,拉茲函數的返回值,用於維護對象實例。

變量o是自動的,引用的對象會自動設置爲無,當函數返回,但你是如此地實例值未設置在函數返回拉茲,可能給客戶端代碼分配值。

此外,如果該對象碰巧引用了用戶控件,則可能無法卸載包含它的用戶表單