Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the target of a weak reference in a safe way

Consider this code:

var weakRef = new WeakReference(new StringBuilder("Mehran"));
if (weakRef.IsAlive)
{
    // Garbage Collection might happen.
    Console.WriteLine((weakRef.Target as StringBuilder).ToString());
}

It's possible for GC.Collect to run after checking weakRef.IsAlive and before using the weakRef.Target.

Am I wrong with this? If it's possible, ss there a safe way to do that?

For example an API like weakRef.GetTargetIfIsAlive() would be appropriate.

like image 613
mehrandvd Avatar asked Feb 13 '13 15:02

mehrandvd


2 Answers

That API already exists; weakRef.Target returns null if the object has already been garbage collected.

StringBuilder sb = weakRef.Target as StringBuilder;
if (sb != null)
{
    Console.WriteLine(sb.ToString());
}
like image 112
Michael Liu Avatar answered Sep 19 '22 10:09

Michael Liu


The IsAlive property does not exist for the benefit of code which will want to use the target if it is alive, but rather for the benefit of code which wants to find out if the target has died but wouldn't be interested in accessing it in any case. If code were to test Target against null, that would cause Target to momentarily have a strong rooted reference (the code that's testing against null), and it's possible that the act of generating such a rooted reference might prevent the object from being garbage-collected when it otherwise would be. If the code isn't interested in Target except to find out whether it has yet been invalidated, there's no reason for code to get the reference. It can simply test IsAlive instead, and take suitable action if it returns false.

like image 45
supercat Avatar answered Sep 19 '22 10:09

supercat