MEF 的对象破坏问题

发布于 2024-10-06 22:24:43 字数 400 浏览 0 评论 0原文

我使用静态变量来保存对象的数量。在构造函数中我增加了这个变量。这样我就知道创建了多少个对象实例。 使用对象后,它们将被解除引用。 我怀疑 MEF 是否持有对这些对象的引用,因此我强制 GC 进行清理(使用 GC.Collect() 方法)。我预计在下一个对象创建时,该变量从零开始,但从最后一个数字恢复。我在析构函数中放置了一个日志机制来进行跟踪,只有在应用程序关闭后对象才会被销毁。 我可以假设 MEF 已经创建了对这些对象的其他引用吗?

我使用 MEFExportFactory 创建我的对象

编辑:

也许应该用 ExportLifetimeContext 完成一些事情?

I use a static variable for holding the count of objects. In constructor I increase this variable. This way I know how many instances of the object are created.
After using the objects, they are leaved dereferenced.
I'm doubtful if MEF is holding references to these objects so I force GC to do a clean up (Using GC.Collect() method). I expect on next object creation this variable start from zero but it resumes from last number. I put a logging mechanism in destructor for tracing, and objects are destroyed only after the application is closed.
Can I assume MEF has created other references to those objects ?

I use MEF and ExportFactory for creating my objects

Edit:

Maybe something with ExportLifetimeContext should be done ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晚风撩人 2024-10-13 22:24:43

我强制 GC 进行清理

如果 MEF 仍然引用对象,那么显然这不会执行任何操作。如果对象已成为垃圾,那么垃圾收集器将自动收集它们 - 要求它明确执行此操作只是一个可能会被忽略的提示。不管怎样,这都是没有必要的。

我在析构函数中放置了日志记录机制以进行跟踪,只有在应用程序关闭后对象才会被销毁。我可以假设 MEF 已经创建了对这些对象的其他引用吗?

MEF 将保存对已创建对象的引用,以便在您请求导出时能够重复返回相同的引用。要要求 MEF 放弃这些引用,您应该调用 CompositionContainer.Dispose。显然,此后您不能再重复使用该容器,尽管您可以创建一个新容器。

MEF 也是它创建的任何IDisposable 对象的所有者。这意味着当您处置容器时,它将在放弃引用之前对任何此类对象调用Dispose

最好依靠调用 Dispose 来执行清理,而不是使用终结器。 无法保证终结器会运行

编辑:

我需要在使用后销毁该对象。但我不想破坏容器。我希望 MEF 作为一个工厂来创建询问部分的新实例,并且调用者应该能够在不再需要时销毁该对象。你能帮忙吗?

这就是 ExportFactory 的用途。 (它以前称为 PartCreator)。不幸的是,除非您使用 Silverlight,否则它在 .NET 4 中尚不可用。您可以使用 codeplex 中的预览版来尝试一下。

如果您不想使用 MEF 的预览版本,您可以通过创建包装容器的工厂类并使用其 GetExport 自行实现类似 ExportFactory 的功能> 和 ReleaseExport 方法来获取和释放对象。如果您需要创建同一部件的多个实例,请不要忘记设置 PartCreationPolicy

编辑2:
我不知何故错过了您一直在使用 ExportFactory 。使用完该对象后,您只需调用 ExportLifeTimeContext.Dispose 即可!

I force GC to do a clean up

If MEF still has references to the objects, then obviously this doesn't do anything. If the objects have become garbage, then the garbage collector will automatically collect them - asking it to do that explicitly is just a hint that might be ignored. Either way, this is not necessary.

I put a logging mechanism in destructor for tracing, and objects are destroyed only after the application is closed. Can I assume MEF has created other references to those objects ?

MEF will hold references to created objects so that it is able to repeatedly return the same reference when you ask for an export. To ask MEF to abandon these references, you should call CompositionContainer.Dispose. Obviously you cannot reuse the container any more after that, though you could create a new one.

MEF is also the owner of any IDisposable objects it creates. This means that when you dispose the container, it will call Dispose on any such objects before abandoning the reference.

It is preferable to rely on calls to Dispose to perform cleanup, rather than to use finalizers. There is no guarantee that finalizers are run at all.

edit:

I need to destroy the object after using it. But I don't want to destroy the container. I want MEF as a factory for creating new instances of asking part, and the caller should be capable of destroying the object when he doesn't need anymore. Can you help with this ?

This is what ExportFactory is for. (It was formerly called PartCreator). Unfortunately it is not yet available in .NET 4, unless you use Silverlight. You can use the preview releases from codeplex to already give it a try.

If you don't want to use the preview releases of MEF, you might be able to implement something like ExportFactory yourself by creating factory classes that wrap the container and by using its GetExport and ReleaseExport methods to acquire and release objects. Don't forget to set a PartCreationPolicy if you need to create multiple instances of the same part.

edit 2:
I somehow missed that you were already using ExportFactory all along. You simply need to call ExportLifeTimeContext.Dispose when you're done with the object!

倦话 2024-10-13 22:24:43

CLR 中对象的及时“销毁”(即终结)并不是一件值得依赖的好事情。如果您这样做是为了调试目的,则没有必要。您可以按照我对此问题的回答中的说明来找出仍有多少某种类型的对象:

C# WPF 中的内存泄漏

如果您确实尝试让软件的行为取决于尚未被 GC 回收的类实例的数量,那么您需要重新考虑您的设计。有几种更好的方法可以实现您想要的目标。

The timely "destruction" (that is finalization) of objects in the CLR is not a good thing to rely on. If you're doing this for debugging purposes, there's no need. You can find out how many objects of some type are still in existence by following the instructions in my answer to this question:

Memory Leaks in C# WPF

If you are genuinely trying to make your software's behaviour depend on a count of the number of instances of a class that have not been reclaimed by the GC, then you need to rethink your design. There will be several better ways of achieving what you want.

我很坚强 2024-10-13 22:24:43

对于共享对象,只要容器处于活动状态,MEF 就会保留对它们的引用。您可以在适当的情况下尽早处置非共享部件。如果您使用 ExportFactory,则需要处置 CreateExport 方法返回的 ExportLifetimeContext,以处置作为请求的一部分创建的任何非共享部分。如果您在容器上调用了 GetExport 方法,则可以调用 ReleaseExport 方法。如果您以其他方式获得导出(即 SatisfyImports 或其他方式),则无法释放它们,因此您可能需要重构应用程序以使用 ExportFactory 或 GetExport。

For shared objects, MEF will keep references to them as long as the container is alive. You can have NonShared parts be disposed early in the right circumstances. If you are using ExportFactory, you need to dispose the ExportLifetimeContext returned by the CreateExport method to dispose any NonShared parts created as part of the request. If you called a GetExport method on the container, you can call the ReleaseExport method. If you got the exports some other way (ie SatisfyImports or something), there isn't a way to release them so you may want to refactor your application to use ExportFactory or GetExport.

谁把谁当真 2024-10-13 22:24:43

MEF 现在有支持 ExportFactory 的桌面版本。尽管名称中有“导出”一词,但您应该在执行“导入”时实现它。调用 CreateExport() 方法来创建部件的新实例将返回 ExportLifetimeContext,此对象具有 Dispose() 稍后可用于释放导出对象的方法。此方法会自动调用您的对象 Dispose(),您无需手动调用它。

此行为是因为容器本身就是所创建对象的所有者,即使调用这些对象的 Dispose() 引用也不会对其产生任何影响。

MEF now has a desktop version which supports ExportFactory. Although the name has 'export' word, you should implement it where you are doing your 'imports'. A call to CreateExport() method for creating a new instance of your part will return an ExportLifetimeContext<T> an this object has a Dispose() method which could be used later for releasing exported object. This method would call your object Dispose() automatically and you don't need to call it manually.

This behavior is because the container is the owner of created objects by itself and even with a reference to these objects calling their Dispose() has no effect on them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文