.NET: способ определить, есть ли у объекта какие-либо ссылки на него? - PullRequest
9 голосов
/ 12 августа 2010

Q. Есть ли способ узнать, имеет ли объект какие-либо "сильные ссылки" на него?


Раймонд Чен намекнул, что решение может бытьвозможный :

Вы хотите знать, является ли счетчик ссылок нулевым или ненулевым.Для этого используйте WeakReference.

Примечания

  • У меня есть " слабая ссылка " на объект (используя WeakReference ).Если бы у меня была сильная ссылка , ответ был бы немедленно: «Да. У вас есть сильная ссылка на объект.»
  • сборщик мусора не дает ответов
  • свойство IsAlive может только сказать вам, был ли объект собран или нет.Нет, если есть сильные ссылки на это или нет.(Объект без ссылок может быть не выбран - GC просто еще не дошел до него)
  • объекты в .NET не считаются ссылками
  • не все объекты должны имплицировать IDisposable интерфейс
  • не все объекты мои

Пример кода

Этот пример кода демонстрирует проблемы с использованием принудительного сбора мусора иСвойство WeakReference IsAlive, чтобы определить, есть ли у объекта какие-либо выдающиеся ссылки на него.

WeakReference m_wr = null;

...

for (int i = 0; i < 1000000; i++)
{
   Pig p = new Pig();
   m_wr = new WeakReference(p);
}

...

GC.Collect();
if (m_wr.IsAlive)
   Environment.FailFast("All objects should have been collected by now");

Ответы [ 3 ]

9 голосов
/ 12 августа 2010

Нет, не без использования API отладчика.

Как вы говорите, объекты не считаются по ссылкам ... поэтому единственный способ выяснить это - просканировать кучу, что обычно происходит просто какчасть сборки мусора.

Обратите внимание, что даже после отсутствия "нормальных" сильных ссылок, объект может быть воскрешен в любом случае как часть финализации - фактически, очередь финализатора имеет ссылку на него, если у него есть финализатор,Возможно, в любом случае вы не захотите включать объект как «без ссылки».

3 голосов
/ 12 августа 2010

Первый звонок GC.Collect() и , затем , чек WeakReference.IsAlive.Если это true (т. Е. Оно не было собрано после вызова GC.Collect ), то где-то есть сильная ссылка.

2 голосов
/ 12 августа 2010

Вы должны прочитать пост Раймонда Чена о количестве ссылок со вчерашнего дня.После этого вы должны решить, действительно ли это то, что вам нужно, и почему.Затем вернитесь и скажите нам, почему.

Хм, кажется, вы прочитали пост - впитали мелкие детали и упустили смысл.


Я хочу знать, еслибезопасно утилизировать соединение с базой данных.

Прочитайте документы. Утилизировать вызовы Закрыть. Закрыть безопасно вызывать столько, сколько вам нужно.

Приложение может вызывать кнопку «Закрыть» более одного раза.Никаких исключений не генерируется.

...