Seguridad para subprocesos de WeakReference
-
18-09-2019 - |
Pregunta
Cuando se utiliza un WeakReference, ¿cómo podemos estar seguros de que el objetivo no se recoge entre el .IsAlive y .target llama?
Por ejemplo:
if (myWeakReference.IsAlive)
{
// How can we be sure the object is still alive while here?
((MyType)myWeakReference.Target).Foo();
}
Solución
Acaba de obtener el Target
y comprobar si no es nulo:
object target = myWeakReference.Target;
if (target != null)
{
((MyType)target).Foo();
}
href="http://msdn.microsoft.com/en-us/library/system.weakreference.isalive.aspx" para IsAlive
dicen específicamente:
Debido a que un objeto podría ser potencialmente recuperadas para la recolección de basura inmediatamente después de la propiedad IsAlive devuelve true, el uso de esta propiedad es no se recomienda a menos que esté probando sólo por un valor de retorno falso.
Otros consejos
El único propósito de la propiedad "IsAlive" es para situaciones en las que desee tomar alguna acción si el objetivo de un WeakReference ya ha sido destruido, pero en el que no quiere correr el riesgo mantenerla viva más tiempo del necesario accidentalmente. Si uno fuera a decir, por ejemplo.
if (someWeakReference.Target == null) cleanup_related_object();
y el recolector de basura fueron (por cualquier razón) gatillo derecho después del código que evalúa someWeakReference.Target, el GC se daría cuenta de que existía una fuerte referencia a ese objeto y se opone a su colección. Por otro lado, diciendo:
if (!someWeakReference.IsAlive) cleanup_related_object();
no habría riesgo de prolongar el tiempo de vida accidentalmente del objetivo de la meta someWeakReference
No se puede. Asignar myWeakReference.Target a una variable, y comprobar si hay nula.