17

使用 Wea​​kReference 时,我们如何确定在 .IsAlive 和 .Target 调用之间没有收集目标?

例如:

if (myWeakReference.IsAlive)
{
    // How can we be sure the object is still alive while here?
    ((MyType)myWeakReference.Target).Foo();
}
4

4 回答 4

29

只需获取Target并检查它是否不为空:

object target = myWeakReference.Target;
if (target != null)
{        
    ((MyType)target).Foo();
}

文档IsAlive专门说:

因为对象可能会在 IsAlive 属性返回 true 后立即被回收以进行垃圾回收,所以不建议使用此属性,除非您只测试 false 返回值。

于 2009-11-06T11:36:58.077 回答
4

"IsAlive" 属性的唯一用途是,如果 WeakReference 的目标已经被破坏,您想采取一些行动,但又不想冒险意外地使其存活时间超过必要的时间。如果有人说,例如

  if (someWeakReference.Target == null)
    cleanup_related_object();

并且垃圾收集器将(无论出于何种原因)在评估 someWeakReference.Target 的代码之后立即触发,GC 会注意到存在对该对象的强引用并排除其收集。另一方面,说:

  if (!someWeakReference.IsAlive)
    cleanup_related_object();

不会有意外延长 someWeakReference 目标的生命周期的风险

于 2011-12-11T17:28:39.143 回答
2

你不能。将 myWeakReference.Target 分配给一个变量,并检查是否为空。

于 2009-11-06T11:38:48.673 回答
-1

你可以摆脱 if :)

(myWeakReference?.Target as MyType)?.Foo()

于 2021-10-09T01:11:56.023 回答