Dot-Net

MEF 保留對 NonShared IDisposable 部分的引用,不允許它們被 GC 收集

  • July 3, 2019

我在 MEF 的部分生命週期中遇到了一些問題,這會導致我的 Prism 應用程序中的記憶體洩漏。

我的應用程序導出視圖和視圖模型並PartCreationPolicy設置為CreationPolicy.NonShared. 視圖和視圖模型分別繼承自ViewBaseViewModelBase,它們實現了IDisposable.

現在,由於我的元件實現IDisposable了,對它們的引用由容器保存,這導致它們不會被垃圾收集器釋放。根據零件壽命的 MEF 文件,這是設計使然:

除非滿足以下條件之一,否則容器不會保存對其創建的元件的引用:

  • 該部分標記為Shared
  • 該部分實現IDisposable
  • 一個或多個導入配置為允許重組

那麼我怎樣才能讓 MEF 不保留對這些部分的引用呢?是否有一個屬性可以讓 MEF 知道我不希望它保留對我的部分的引用,即使它實現了IDisposable

上述文章中討論的兩種策略對我來說似乎都不是好的解決方案:

  • ReleaseExport需要一個對Export像作為參數,我不知道如何提供。我有我的視圖實例,但我無法知道用於創建視圖的契約是什麼。如果有一個ReleaseExport可以接收容器創建的任何對象的重載,那就太好了。
  • 使用子容器似乎也不是一個自然的選擇。

任何幫助將不勝感激。

除非 Prism 支持視圖對象的某種生命週期,否則這裡沒有解決方案,除了IDisposable從視圖公開的介面列表中刪除。

有三種 MEF 方法來處理這個問題,其他響應者都提到了:

  • ExportFactory<T>
  • 子容器
  • ReleaseExport()

所有這些都需要對請求原始導出的程式碼部分進行一些工作 - 在這種情況下是 Prism 中的程式碼。這是有道理的,因為不希望使用對象的程式碼必須知道它是如何以及何時創建的。

MEF中沒有ReleaseExportedObject(),因為多個(例如屬性)導出可以返回相同的值;在邏輯上可能提供,但增加的複雜性使其不太可能在可預見的未來由 MEF 解決。

希望這可以幫助; 我已將這個問題重新標記為“棱鏡”,因為我確信 Prism 社區中的其他人會遇到這個問題並能夠提供建議。

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