Утечка памяти через событие
Вопрос
Окно подписывается на событие долгоживущего сервиса service.Updated += OnUpdated; и никогда не отписывается. Что происходит после закрытия окна?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Окно собирается GC, а подписка удаляется автоматически
- Окно не собирается GC: сервис держит делегат, а делегат держит ссылку на окноправильный ответ
- Сервис не собирается GC, потому что окно держит ссылку на него
- При следующем вызове события будет
ObjectDisposedExceptionи подписка удалится
Разбор
Делегат с методом экземпляра хранит ссылку на целевой объект (Target). Список подписчиков события принадлежит сервису, поэтому пока жив сервис, живо и окно со всем, на что оно ссылается. Подписки сами не удаляются, исключения нет: событие просто продолжит вызывать метод «мёртвого» окна. Лечится отпиской в Dispose/OnClosed или слабыми событиями.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Замыкание на переменную цикла for
Следующий вопрос
Чем event отличается от поля-делегата