A Replacement for System.WeakReference
There are two minor problems with the System.WeakReference class: type safety and garbage collection.
The first one is a simple problem;
System.WeakReference only deals with instances of type
object. However, it is not difficult to write a type-safe wrapper for
System.WeakReference that provides type safety.
The second problem is a little more subtle. A weak reference is a wrapper around a
System.Runtime.InteropServices.GCHandle. The core
GCHandle type is both powerful and dangerous; it is halfway unmanaged.
System.WeakReference provides a safer class that only uses
GCHandle as a weak reference.
The problem is that a
GCHandle actually represents an entry in the runtime’s GCHandle table. This table interacts with the garbage collector, preventing some objects from being GC’ed or moved. It is also used to create and track weak references. Logically, allocated GCHandles are unmanaged resources, and
System.WeakReference does clean up its GCHandle correctly in its finalizer.
System.WeakReference does not implement
System.IDisposable. This is not the end of the world, but it does place additional pressure on the garbage collector. It forces every
System.WeakReference into an extra generation, holds the GCHandle table entry longer than necessary (possibly causing extra work for the garbage collector, since it must update the GCHandle table entry when that object is collected), and requires the finalizer thread to actually release the resource.
Nito.WeakReference<T> is a strongly-typed, disposable replacement for
System.WeakReference. [Note, however, that
Nito.WeakReference<T> does not support resurrection, which is a complex use case that is only required in very rare situations.]
A Simple Weak Collection
A weak collection (or more properly, a collection of weak references) at any given time may contain references to both live (referenced) and dead (garbage collected) objects. Removing all the dead objects is called a “purge”. It’s convenient to be able to enumerate the collection both with and without a purge. The
Nito.IWeakCollection<T> defines an interface for enumerable collections of weak references, and includes methods for enumerating or counting the collection both with and without purging. Some of its members include:
CompleteList- Gets a complete sequence of objects from the collection (null entries represent dead objects).
LiveList- Gets a sequence of live objects from the collection, causing a purge.
CompleteCount- Gets the number of live and dead entries in the collection. O(1).
LiveCount- Gets the number of live entries in the collection, causing a purge. O(n).
Nito.WeakCollection<T> is a
List-based implementation of a weak collection. It is used by the Nito MVVM library to track weak events, but it should be useful in other situations as well.