Как работают слабые события?
В настоящее время я изучаю WPF и наткнулся на концепцию слабых событий, но я действительно пытаюсь "получить". Я прочитал бесчисленные статьи о Stackoverflow и посмотрел образцы кода, но он просто не погружается.
Вот моя дилемма:
- Я понимаю, что когда объект подписывается на событие, источник события должен содержать ссылку на подписчика.
- Я также понимаю, что если абонент выходит из области видимости или явно уничтожен, но источник события не уничтожается, то абонент не будет собирать мусор, потому что источник события все еще сохраняет ссылку на подписчика.
- Общим способом избежать этого является явное освобождение подписчика от источника до того, как объект будет уничтожен. Я понимаю, что это может быть проблемой, если программист не может определить, когда это произойдет.
Итак, из приведенного выше я понимаю, как использование событий может привести к утечкам памяти и почему существует необходимость в слабом шаблоне ссылок, но то, что мешает мне понять, - это то, как шаблон слабых событий действительно достигает этой цели? Что он делает по-другому?
Конечно, даже если есть класс, который управляет событиями, он все равно должен подписаться и не подписаться с обработчиками в/из источника, поэтому ссылки должны существовать, что дает те же проблемы со стандартным способом использования событий.
Кто-нибудь, пожалуйста, объясните мне, какую фундаментальную концепцию я пропускаю или недопонимаю, и помогите мне "получить" шаблон слабых событий.
Ответы
Ответ 1
Что вам не хватает, так это то, что Weak Events (которые используют Weak References под обложками, которые, в свою очередь, используют GCHandle) используют встроенное поведение CLR для конкретного случая необходимости доступа к объекту без ссылки на него, то есть они не ограничены обычные "правила", на которые распространяется ваш код приложения.
См. http://sankarsan.wordpress.com/2008/08/09/weak-references/
За кулисами WeakEventManager имеет слабую ссылку на подписчика событий. Если подписчик окажется GC'd до того, как событие будет поднято, WeakEventManager просто пожимает плечами и говорит: "Хорошо, этот парень мертв, я просто перестану пытаться уведомить его об этом событии с этого момента"