2010-12-06 120 views
1

我使用一個靜態變量來保存對象的數量。在構造函數中我增加了這個變量。這樣我就知道創建了多少個對象實例。 使用這些對象後,它們被取消引用。 我懷疑MEF是否持有對這些對象的引用,所以我強制GC做清理(使用GC.Collect()方法)。我期望在下一個對象創建這個變量從零開始,但它從最後一個數字恢復。我在destructor中設置了一個日誌記錄機制用於跟蹤,並且只有在應用程序關閉後纔會銷燬對象。 我可以假設MEF已創建對這些對象的其他引用嗎?MEF對象破壞問題

我用MEFExportFactory創建我的對象

編輯:

或許真的與ExportLifetimeContext應該怎麼辦?

回答

0

MEF現在有一個桌面版本,它支持ExportFactory。雖然這個名字有'出口'這個詞,但是你應該在你進行'進口'的地方執行它。如果要調用CreateExport()創建零件的新實例的方法將返回ExportLifetimeContext<T>,該對象有一個Dispose()方法,該方法稍後可用於釋放導出的對象。這種方法會自動調用你的對象Dispose(),你不需要手動調用它。

此行爲是因爲容器本身是創建對象的所有者,甚至對這些調用其對象Dispose()的對象的引用也沒有影響。

1

CLR中對象的及時「破壞」(即定稿)並不是一件好事。如果您爲了調試目的而這樣做,則不需要。你可以找到某種類型的有多少對象仍然存在通過遵循我的回答說明瞭這個問題:

Memory Leaks in C# WPF

如果你真的試圖讓你的軟件的行爲依賴的計數,沒有被GC回收的類的實例數量,那麼你需要重新考慮你的設計。會有幾種更好的方法來實現你想要的。

8

我強迫GC做一個清理

如果MEF仍具有對對象的引用,那麼顯然這並沒有做任何事情。如果對象已經變成垃圾,那麼垃圾收集器會自動收集它們 - 要求它這樣做顯然只是一個可能被忽略的提示。無論哪種方式,這都沒有必要。

我把一個日誌記錄機制放在析構函數中進行跟蹤,只有在關閉應用程序後才銷燬對象。我可以假設MEF已經創建了這些對象的其他引用嗎?

MEF將持有對創建對象的引用,以便在您要求導出時能夠重複返回相同的引用。要讓MEF放棄這些參考資料,您應該致電CompositionContainer.Dispose。顯然你不能再使用容器了,儘管你可以創建一個新容器。

MEF也是其創建的任何IDisposable對象的所有者。這意味着當您處理容器時,在放棄參考之前,它將調用Dispose任何此類對象。

最好依靠致電Dispose來執行清理,而不是使用終結器。 There is no guarantee that finalizers are run at all

編輯:

我需要使用後銷燬的對象。但我不想破壞容器。我希望MEF作爲創建詢問部件的新實例的工廠,並且調用者應該能夠在不再需要時摧毀對象。你能幫忙嗎?

這是ExportFactory的用途。 (它以前被稱爲PartCreator)。不幸的是,除非你使用Silverlight,否則它還不能在.NET 4中使用。您可以使用codeplex的預覽版本試用。

如果你不想使用MEF的預覽版中,你也許能夠通過創建工廠類,包裝容器,並利用其GetExportReleaseExport方法來獲取和釋放,實現諸如ExportFactory自己的東西對象。如果您需要創建同一零件的多個實例,請不要忘記設置PartCreationPolicy

編輯2: 我不知何故錯過了你已經在使用ExportFactory一直。當你完成對象時,你只需要調用ExportLifeTimeContext.Dispose

+1

我需要在使用它之後銷燬對象。但我不想破壞容器。我希望MEF作爲創建詢問部件的新實例的工廠,並且調用者應該能夠在不再需要時摧毀對象。你能幫忙嗎? – Xaqron 2010-12-06 17:07:17

1

對於共享對象,只要容器處於活動狀態,MEF就會保持對它們的引用。您可以在正確的情況下儘早處理NonShared零件。如果您使用的是ExportFactory,則需要處置由CreateExport方法返回的ExportLifetimeContext以處理作爲請求一部分創建的任何NonShared部件。如果您在容器上調用了GetExport方法,則可以調用ReleaseExport方法。如果您以其他方式獲得導出(即SatisfyImports或其他方式),則無法釋放它們,因此您可能需要重構應用程序以使用ExportFactory或GetExport。