Adi*_*ter 12 .net memory-leaks prism mef object-lifetime
我在MEF的部件生命周期中遇到了一些问题,导致我的Prism应用程序中出现内存泄漏.
我的应用程序导出视图和视图模型,并将PartCreationPolicy其设置为CreationPolicy.NonShared.视图和视图模型分别继承ViewBase和ViewModelBase实现IDisposable.
现在,由于我的部件实现了IDisposable,因此容器会保留对它们的引用,这会导致它们不被垃圾收集器释放.根据MEF关于部件寿命的文档,这是设计的:
除非满足下列条件之一,否则容器将不会保留对其创建的零件的引用:
- 该部分标记为
Shared- 该部分实现
IDisposable- 一个或多个导入配置为允许重构
那怎么能让MEF不参考这些部分呢?是否有一个属性我可以用来让MEF知道我不希望它保留对我的部分的引用,即使它实现了IDisposable?
上述文章中讨论的两种策略对我来说似乎都不是很好的解决方案:
ReleaseExport需要一个Export对象作为参数,我不知道如何提供.我有我的观点的实例,但是我无法知道用于创建视图的合同是什么.如果有一个重载ReleaseExport可以接收容器创建的任何对象,那将会很棒.任何帮助将不胜感激.
除非Prism支持视图对象的某种生命周期,否则除了IDisposable从视图公开的接口列表中删除之外,此处没有解决方案.
处理此问题有三种MEF方法,其他响应者都提到了这些方法:
ExportFactory<T>ReleaseExport()所有这些都需要在请求原始导出的代码方面做一些工作 - 在这种情况下是Prism中的代码.这是有道理的,因为消费对象的代码必须知道它是如何以及何时被创建的.
ReleaseExportedObject()MEF 中没有,因为多个(例如属性)导出可以返回相同的值; 它在逻辑上可能提供,但增加的复杂性使得MEF在可预见的未来不太可能解决.
希望这可以帮助; 我已经重新提出这个问题'棱镜',因为我相信Prism社区的其他人会遇到这个并能够提供建议.
当你实现时,IDisposable你有点说应该以确定的方式清理类型(IDisposable.Dispose当垃圾收集器决定它是时候时,通过调用而不是随机调用.
在您的情况下,视图模型将仅在您处置可能不是您想要的容器时处理.为了解决这个问题,我看到两种可能的解决方
不要IDisposable在视图模型上实现.显然你不关心他们什么时候被清理,为什么要制造呢IDisposable?
您可以使用共享视图模型工厂类,而不是让容器创建非共享的每个视图模型.然后,您可以将该类注入视图模型的所有者,以允许所有者明确创建视图模型.假设这些所有者也知道何时处置视图模型.
基本上,如果某些东西是一次性的,那么在您需要处理一次性物品的代码中也应该是一个明智的点.