开发者

Thread Safety of WeakReference

开发者 https://www.devze.com 2022-12-10 21:52 出处:网络
When using a WeakReference, how can we be sure than the target is not collected between the .IsAlive and .Target calls?

When using a WeakReference, how can we be sure than the target is not collected between the .IsAlive and .Target calls?

For example:

if (myWeakReference.IsAlive)
{
    // How can we be sure the object is still alive while here?
    ((MyType)myWeak开发者_如何学CReference.Target).Foo();
}


Just get the Target and check whether it's not null:

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

The docs for IsAlive specifically say:

Because an object could potentially be reclaimed for garbage collection immediately after the IsAlive property returns true, using this property is not recommended unless you are testing only for a false return value.


The only purpose of the "IsAlive" property is for situations where you want to take some action if the target of a WeakReference has already been destroyed, but where you don't want to risk accidentally keeping it alive longer than necessary. If one were to say, e.g.

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

and the garbage-collector were to (for whatever reason) trigger right after the code that evaluated someWeakReference.Target, the GC would notice that there existed a strong reference to that object and preclude its collection. On the other hand, saying:

  if (!someWeakReference.IsAlive)
    cleanup_related_object();

there would be no risk of accidentally prolonging the lifetime of the target of someWeakReference target


You can't. Assign myWeakReference.Target to a variable, and check for null.


you can get rid of the if :)

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

0

精彩评论

暂无评论...
验证码 换一张
取 消