【发布时间】:2015-12-23 09:31:18
【问题描述】:
我有一个来自 TypeA 的复杂类(TypeA 不是我创建的)。
class TypeA { }
这些对象由我无权访问的不同类持有:
class TypeB { private TypeA TypeAObject; }
class TypeC { private TypeA TypeAObject; }
我的 Own Class 中也有对 TypeA 的引用。
class MyClass { private TypeA TypeAObject; }
现在我有以下问题。如果我的类是从垃圾收集器中收集的,TypeAObject 不会被释放,因为 TypeAObject 上仍有 TypeB 和 TypeC 的引用。
对于这个问题,我认为 WeakReferenc 会是解决方案:
class MyClass { private WeakReference<TypeA> TypeAObject; }
按预期工作了很长时间,但有时 TypeB 或 TypeC 需要来自 TypeA 的对象。对于这个问题,我认为也有解决方案。 TypeA 对象有一个我可以使用的 Unloaded 事件。在此之后,没有人再次使用该对象。所以我只是在 unloaded 事件中将 Object 从 TypeA 设置为 WeakReference。
class MyClass
{
private TypeA TypeAObject;
private WeakReference<TypeA> TypeAObjectWeak;
public void SetUnloaded()
{
TypeAObject.Unloaded = () => {TypeAObjectWeak = new WeakReference<TypeA>(TypeAObject) };
}
}
但是没有收集 TypeAObject。这就是我现在的问题:有没有办法按需将 Object 设置为 WeakReference?
编辑
在我的例子中,TypeA 类是 WorkflowApplication 类型的类 (http://referencesource.microsoft.com/#System.Activities/System/Activities/WorkflowApplication.cs,533e298006a3d9ca)
=> 问题在于 WorkflowApplication 的事件(即 UnhandledException、Idle、...)。将它们设置为 null 后,对象被收集。
【问题讨论】:
-
如果
TypeB和TypeC持有TypeA的引用,来自MyClass的WeakReference将如何提供帮助?您需要弄清楚如何清除这些引用,或者确保TypeB和TypeC对象也符合垃圾回收条件。很遗憾,我们无法真正帮助您做到这一点。 -
为什么你觉得有必要控制这个?由于其他一些对象(TypeB 或 TypeC 类型)仍然存在,所以该对象仍在内存中是否存在问题?
-
有一些方法可以处理这些事情,尽管我们无法用这么少/通用的信息来判断它们是否安全。例如,如果通过这些类型的接口访问对象,您可以构建自己的该接口的实现来保存实际(昂贵的?)对象。这将允许您控制这个(昂贵的)对象的生命周期,即使 TypeB 和 TypeC 仍然引用您的接口实现(包装器)对象。
-
问题出在 WorkflowApplication 的事件上(即 UnhandledException、Idle、...)。将它们设置为 null 后,对象被收集。