16

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)myWeakReference.Target).Foo();
}
MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
Khash
  • 2,500
  • 4
  • 30
  • 56

4 Answers4

29

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

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

supercat
  • 77,689
  • 9
  • 166
  • 211
2

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

janm
  • 17,976
  • 1
  • 43
  • 61
-1

you can get rid of the if :)

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