问题
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();
}
回答1:
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.
回答2:
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
回答3:
You can't. Assign myWeakReference.Target to a variable, and check for null.
来源:https://stackoverflow.com/questions/1687045/thread-safety-of-weakreference