MEF 保留对 NonShared IDisposable 部分的引用,不允许它们被 GC 收集 [英] MEF keeps reference of NonShared IDisposable parts, not allowing them to be collected by GC

查看:29
本文介绍了MEF 保留对 NonShared IDisposable 部分的引用,不允许它们被 GC 收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 MEF 的部件生命周期中遇到了一些问题,这会导致我的 Prism 应用程序出现内存泄漏.

I've encountered somewhat of a problem in MEF's part lifetime which causes memory leaks in my Prism application.

我的应用程序导出视图和视图模型,其中 PartCreationPolicy 设置为 CreationPolicy.NonShared.视图和视图模型分别继承自 ViewBaseViewModelBase,它们实现了 IDisposable.

My application exports views and viewmodels with the PartCreationPolicy being set to CreationPolicy.NonShared. The views and viewmodels inherit from ViewBase and ViewModelBase respectively, which implements IDisposable.

现在,由于我的部分实现了 IDisposable,对它们的引用由容器保存,这导致垃圾收集器不会释放它们.根据关于零件寿命的MEF文档,这是设计使然:

Now, since my parts implement IDisposable, a reference to them is kept by the container, which causes them to not be released by the garbage collector. According to MEF documentation on part lifetime, this is by design:

除非满足以下任一条件,否则容器不会保存对其创建的部件的引用:

The container will not hold references to parts it creates unless one of the following is true:

  • 该部分被标记为Shared
  • 该部分实现了IDisposable
  • 一个或多个导入配置为允许重新组合

那我怎样才能让 MEF 不保留对这些部分的引用?是否有一个属性可以让 MEF 知道我不希望它保留对我的部分的引用,即使它实现了 IDisposable?

How then can I make MEF not keep a reference to these parts? Is there an attribute I can use to let MEF know I don't want it to keep a reference to my part even if it implements IDisposable?

以上文章中讨论的两种策略对我来说都不是很好的解决方案:

Both of the strategies discussed in the above article don't seem like good solutions for me:

  • ReleaseExport 需要一个 Export 对象作为参数,我不知道如何提供.我有我的视图实例,但我无法知道用于创建视图的合同是什么.如果 ReleaseExport 有一个可以接收容器创建的任何对象的重载,那就太好了.
  • 使用子容器似乎也不是一个自然的选择.
  • ReleaseExport requires an Export object as a parameter, which I don't know how to provide. I have the instance of my view, but there's no way for me to know what was the contract that was used to create the view. It would've been great if there was an overload for ReleaseExport which could receive any object created by the container.
  • Using a child container doesn't seem like a natural option either.

任何帮助将不胜感激.

推荐答案

除非 Prism 支持某种视图对象的生命周期,否则这里没有解决方案,只能从暴露的接口列表中删除 IDisposable通过视图.

Unless Prism supports some kind of lifetime for view objects, there is no solution here except to remove IDisposable from the list of interfaces exposed by the view.

其他响应者都提到了三种 MEF 方法来处理此问题:

There are three MEF approaches to handling this problem, all mentioned by other responders:

  • ExportFactory
  • 子容器
  • ReleaseExport()

所有这些都需要对请求原始导出的代码部分进行一些工作 - 在这种情况下是 Prism 中的代码.这是有道理的,因为使用对象的代码必须知道它是如何以及何时创建的,这是不可取的.

All of them require some work on the part of the code that requests the original export - in this case code within Prism. This makes some sense, as it is undesirable for code consuming an object to have to be aware of how and when it was created.

MEF 中没有 ReleaseExportedObject() 因为多个(例如属性)导出可以返回相同的值;在逻辑上可能提供,但增加的复杂性使得 MEF 在可预见的未来不太可能解决这个问题.

There is no ReleaseExportedObject() in MEF because multiple (e.g. property) exports can return the same value; it may be logically possible to provide but the added complexity makes it unlikely to be addressed by MEF in the foreseeable future.

希望这有帮助;我已将这个问题重新标记为棱镜",因为我相信棱镜社区中的其他人会遇到这个问题并能够提供建议.

Hope this helps; I've retagged this question 'prism' as I'm sure others in the Prism community will have encountered this and be able to offer advice.

这篇关于MEF 保留对 NonShared IDisposable 部分的引用,不允许它们被 GC 收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆