Безопасность потока WeakReference
При использовании WeakReference, как мы можем быть уверены, что цель не собирается между вызовами .IsAlive и .Target?
Например:
if (myWeakReference.IsAlive)
{
// How can we be sure the object is still alive while here?
((MyType)myWeakReference.Target).Foo();
}
Ответы
Ответ 1
Просто запустите Target
и проверьте, не является ли оно нулевым:
object target = myWeakReference.Target;
if (target != null)
{
((MyType)target).Foo();
}
docs для IsAlive
специально говорят:
Поскольку объект потенциально может быть регенерированный для сбора мусора сразу после свойства IsAlive возвращает true, используя это свойство не рекомендуется, если вы не тестируете только для ложного возвращаемого значения.
Ответ 2
Единственная цель свойства IsAlive - это ситуации, когда вы хотите предпринять какие-то действия, если цель WeakReference уже уничтожена, но где вы не хотите рисковать случайно, сохраняя ее дольше, чем необходимо. Если можно сказать, например,
if (someWeakReference.Target == null)
cleanup_related_object();
и сборщик мусора должен (по какой-либо причине) запускать сразу после кода, который оценил значение SomeWeakReference.Target, GC заметил бы, что существовала сильная ссылка на этот объект и исключала его сбор. С другой стороны, говоря:
if (!someWeakReference.IsAlive)
cleanup_related_object();
не было бы риска случайного продления срока жизни цели какой-либо цели WeakReference
Ответ 3
Вы не можете. Назначьте myWeakReference.Target к переменной и проверьте значение null.