.NET: Как определить, есть ли у объекта ссылки на него?

В. Есть ли способ узнать, есть ли у объекта какие-либо «сильные ссылки» на него?


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

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

Примечания

  • У меня есть « слабая ссылка » на объект (с использованием WeakReference ). Если бы у меня была сильная ссылка , ответ был бы немедленно: «Да. У вас есть сильная ссылка на объект».
  • сборщик мусора не предоставляет ответов
  • свойство IsAlive может только сказать вам, был ли объект собран или нет. Нет, есть ли на это сильные ссылки или нет. (Объект без ссылок может быть не собран - сборщик мусора еще не дошел до него)
  • объектов в. 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");

10
задан Ian Boyd 13 August 2010 в 15:21
поделиться

3 ответа

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

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

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

9
ответ дан 3 December 2019 в 23:10
поделиться

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

3
ответ дан 3 December 2019 в 23:10
поделиться

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

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


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

Прочтите документацию. Dispose вызывает Close. Закрыть можно безопасно звонить сколько угодно.

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

2
ответ дан 3 December 2019 в 23:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: