4

I would like to keep a list of a certain class of objects in my application. But I still want the object to be garbage collected. Can you create weak references in .NET?

For reference:

Answer From MSDN:

To establish a weak reference with an object, you create a WeakReference using the instance of the object to be tracked. You then set the Target property to that object and set the object to null. For a code example, see WeakReference in the class library.

Community
  • 1
  • 1
Frank Krueger
  • 69,552
  • 46
  • 163
  • 208

4 Answers4

12

Yes, there's a generic weak reference class.

MSDN > Weak Reference

arul
  • 13,998
  • 1
  • 57
  • 77
5

Can you create weak references in .NET?

Yes:

WeakReference r = new WeakReference(obj);

Uses System.WeakReference.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
3

Yes...

There is a pretty good example to be found here:

http://web.archive.org/web/20080212232542/http://www.robherbst.com/blog/2006/08/21/c-weakreference-example/

In your class you created two member variables:

WeakReference _weakRef = null;

Person _strongRef = null;

You created two new Person objects (which are simple objects I just created for this example, consisting of a Name property and some reference tracking code). Next you set the member variables to the newly created instances of the Person objects.

_strongRef = p;

_weakRef = new WeakReference(p1);

The difference here you’ll notice that _strongRef is just a regular normal reference, whereas _weakRef is set to a WeakReference object with the person object (p1) passed in as a parameter in the constructor.

If a garbage collection were to occur, or just for testing purposes you called it yourself with:

GC.Collect();

Then the p1 target object that is held by the _weakRef member variable should be garbage collected. You can write code to check:

if (_weakRef.IsAlive)

If the WeakReference is still alive you can convert the WeakReference to a strong or normal reference by using code like this:

Person p = _weakRef.Target as Person;

Now the p reference is treated as a strong reference and won’t be collected until it is no longer used. If you wanted to keep the reference around after the scope you could set that to a member variable.

Razvan Dumitru
  • 11,815
  • 5
  • 34
  • 54
Andrew Rollings
  • 14,340
  • 7
  • 51
  • 50
0

Here is the full (non thread safe) implementation sample of WeakReference

ClassA objA = new ClassA();
WeakReference wr = new WeakReference(objA);
// do stuff 
GC.Collect();
ClassA objA2;
if (wr.IsAlive)
    objA2 = wr.Target as ClassA; 
else
    objA2 = new ClassA(); // create it directly if required

WeakReference is in the System namespace hence no need to include any special assembly for it.

Binoj Antony
  • 15,886
  • 25
  • 88
  • 96
  • 3
    This contains a race condition, doesn't it? What if between `if (wr.IsAlive)` and `objA2 = wr.Target as ClassA;` the object gets collected? `wr.Target` (and thus `objA2`) would be null. – Sebastian Negraszus Jan 04 '13 at 15:10
  • Presumably the Target property is null after the object has been garbage collected. The MSDN docs state that using IsAlive is subject to a race condition, but does not say explicitly how to resolve the problem. http://msdn.microsoft.com/en-us/library/system.weakreference.isalive.aspx – avl_sweden Jan 18 '13 at 05:13
  • @avl_sweden: If one will want to do anything with the target of a weak reference, one should retrieve the target and then check to see if it is null. If it is not null, the referenced object is guaranteed to exist at least as long as one holds the newly-retrieved reference to it. The `IsAlive` property is intended for code which will only be interested in a reference if it's dead; such code could check if `Target` was null, but that might cause the object to be kept alive needlessly. – supercat Jan 25 '14 at 20:11