C#, Как отказаться от подписки все обработчики событий от данного события?

Существует ли простой способ выполнить итерации на всем протяжении обработчиков, подписанных на данное событие? Моя проблема состоит в том, что клиенты подписывают, но забывают отказываться от подписки так, утечка памяти происходит. Мне нужен путь к объекту разъединить все обработчики его событий в Расположить методе, таким образом, утечки не произошло бы - по крайней мере, не из-за событий.

14
задан RredCat 21 September 2015 в 08:41
поделиться

4 ответа

Установите значение null для вашего события: MyEvent = null;

Но действительно лучше заставить клиентов отказаться от подписки на ваше событие.

12
ответ дан 1 December 2019 в 09:12
поделиться

Утечка памяти происходит только в том случае, если другой объект (слушатель) умирает раньше вашего объекта (источника события). В этом случае источник события по-прежнему сохраняет ссылку на слушателя, что предотвращает сбор слушателя. Когда источник события умирает, также может быть собран неподписанный слушатель.

Если источник события умирает раньше слушателя, это не препятствует последующему сбору слушателя, когда все другие ссылки на него имеют значение null.

Это означает, что метод Dispose источника события не подходит для решения этой проблемы. Это может быть решено только в коде слушателя. Говоря простым языком, вы ничего не можете сделать, кроме как попросить своих клиентов написать чистый код.

7
ответ дан 1 December 2019 в 09:12
поделиться

Альтернативный подход - использовать так называемый шаблон «слабого делегата». Когда вы используете этот метод, событие ссылается на клиентов только с помощью WeakReference , который не сохраняет их в памяти. Клиенты будут собираться сборщиком мусора, когда на них больше не будет ссылаться другая часть приложения (и обработчик также может быть автоматически отменен при сборке клиента).

Это обычно используется для решения проблемы с клиентами, которые «забывают» отказаться от подписки на событие .NET, поэтому похоже, что это может хорошо подходить для вашей проблемы.

9
ответ дан 1 December 2019 в 09:12
поделиться

На момент написания наиболее точный ответ наименее популярен.

Вы можете обнулить обработчик события, но он все равно будет заблокирован после того, как его владелец будет заблокирован - это не плохо быть супер аккуратным, но, как говорит Алекс, проблема не в этом.

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

В следующем сообщении блога также рассматривается решение, которое описывает Ади, и объясняется, почему в нем нет необходимости.

http://weblogs.sqlteam.com/mladenp/archive/2007/10/24/C-Care-about-Event-Memory-Leaks-with-Delegate.GetInvocationList.aspx

1
ответ дан 1 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

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