Если у меня есть следующий код:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
Будет ли pClass собирать мусор? Или он будет зависать, продолжая стрелять в события, когда они происходят? Нужно ли делать следующее, чтобы разрешить сборку мусора?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
c#
.net
event-handling
garbage-collection
Марк Инграм
источник
источник
Ответы:
Для конкретного вопроса «Будет ли pClass собирать мусор»: подписка на событие не влияет на сборку pClass (как издателя).
Для GC в целом (в частности, для цели): это зависит от того, является ли MyFunction статической или основанной на экземплярах.
Делегат (такой как подписка на событие) для метода экземпляра включает в себя ссылку на экземпляр. Так что да, подписка на событие помешает GC. Однако, как только объект, публикующий событие (pClass выше), подходит для сбора, это перестает быть проблемой.
Обратите внимание, что это односторонний; т.е. если у нас есть:
тогда «издатель» будет поддерживать «цель» живым, но «цель» не будет поддерживать «издателя» живым.
Так что нет: если pClass будет собираться в любом случае, нет необходимости отписываться от слушателей. Однако, если Pclass был долгожителем (больше , чем например , с MyFunction), то Pclass может сохранить этот экземпляр живым, так что это было бы необходимо отказаться , если вы хотите, чтобы цель , чтобы быть собраны.
Однако по этой причине статические события очень опасны при использовании с обработчиками на основе экземпляров.
источник
WeakReference
, а в некоторых случаях это может быть хорошей идеей, но часто это будет сильной идеей.Да, pClass будет собирать мусор. Подписка на событие не означает, что существует какая-либо ссылка на pClass.
Так что нет, вам не придется отсоединять обработчик, чтобы pClass собирал мусор.
источник
В тот момент, когда на часть памяти больше не ссылаются, она становится кандидатом на сборку мусора. Когда экземпляр вашего класса выходит из области видимости, ваша программа больше не ссылается на него. Он больше не используется и поэтому может быть безопасно собран.
Если вы не уверены, что что-то будет собрано, задайте себе следующий вопрос: существует ли еще ссылка на это? На обработчики событий ссылается экземпляр объекта, а не наоборот.
источник
pClass
будет мусор. Однако, если приведенный выше фрагмент кода находится внутри другого класса, экземпляр этого класса может быть не очищен, если вы не установитеpClass
егоnull
.источник