Выбор ответа Middle Делегаты и события спрашивают часто обновлено

Утечка памяти через событие

Вопрос

Окно подписывается на событие долгоживущего сервиса service.Updated += OnUpdated; и никогда не отписывается. Что происходит после закрытия окна?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Окно не собирается GC: сервис держит делегат, а делегат держит ссылку на окно. Делегат с методом экземпляра хранит ссылку на целевой объект (Target).

Варианты ответа

  1. Окно собирается GC, а подписка удаляется автоматически
  2. Окно не собирается GC: сервис держит делегат, а делегат держит ссылку на окноправильный ответ
  3. Сервис не собирается GC, потому что окно держит ссылку на него
  4. При следующем вызове события будет ObjectDisposedException и подписка удалится

Разбор

Делегат с методом экземпляра хранит ссылку на целевой объект (Target). Список подписчиков события принадлежит сервису, поэтому пока жив сервис, живо и окно со всем, на что оно ссылается. Подписки сами не удаляются, исключения нет: событие просто продолжит вызывать метод «мёртвого» окна. Лечится отпиской в Dispose/OnClosed или слабыми событиями.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме