.NET Framework Références faibles


Exemple

Les références faibles sont ... des références, à d'autres objets (alias "cibles"), mais "faibles" car elles n'empêchent pas ces objets d'être collectés. En d'autres termes, les références faibles ne comptent pas lorsque le récupérateur de place évalue les objets en tant que "live" ou "dead".

Le code suivant:

var weak = new WeakReference<FinalizableObject>(new FinalizableObject());
GC.Collect();

Produit la sortie:

<namespace>.FinalizableObject initialized
<namespace>.FinalizableObject finalized

L'objet est libéré du tas géré bien qu'il soit référencé par la variable WeakReference (toujours dans l'étendue lorsque le récupérateur de place a été appelé).

Conséquence n ° 1: à tout moment, il est dangereux de supposer qu'une cible WeakReference est toujours allouée ou non sur le segment de mémoire géré.

Conséquence n ° 2: chaque fois qu'un programme doit accéder à la cible d'une référence faible, le code doit être fourni pour les deux cas, la cible étant toujours allouée ou non. La méthode pour accéder à la cible est TryGetTarget:

var target = new object(); // Any object will do as target
var weak = new WeakReference<object>(target); // Create weak reference
target = null; // Drop strong reference to the target

// ... Many things may happen in-between

// Check whether the target is still available
if(weak.TryGetTarget(out target))
{
    // Use re-initialized target variable
    // To do whatever the target is needed for
}
else
{
    // Do something when there is no more target object
    // The target variable value should not be used here
}

La version générique de WeakReference est disponible depuis .Net 4.5. Toutes les versions du framework fournissent une version non générique, non typée, construite de la même manière et vérifiée comme suit:

var target = new object(); // Any object will do as target
var weak = new WeakReference(target); // Create weak reference
target = null; // Drop strong reference to the target

// ... Many things may happen in-between

// Check whether the target is still available
if (weak.IsAlive)
{
    target = weak.Target;

    // Use re-initialized target variable
    // To do whatever the target is needed for
}
else
{
    // Do something when there is no more target object
    // The target variable value should not be used here
}