Где «уничтожить» обработчики в классах VB.NET? - PullRequest
1 голос
/ 28 января 2011

У меня есть некоторый класс (пользовательский элемент управления) MyUserControl, который вызывает события.

Я использую его в форме MyForm, в силу чего по некоторым причинам я вынужден использовать AddHandlerWithEvents<>Handles пары.

Я использую AddHandler s в методе MyForm_Load.

Сейчас.Добавление обработчика в порядке, теперь вопрос в том, где удалить этот обработчик.Должно ли это быть сделано в методе Finalize MyForm?à la

Protected Overrides Sub Finalize()
  RemoveHandler _myCtrl.Action1Performed, AddressOf MyControl_Action1Performed  
  RemoveHandler _myCtrl.Action2Performed, AddressOf MyControl_Action2Performed  
  RemoveHandler _myCtrl.Action3Performed, AddressOf MyControl_Action3Performed  
End Sub

Ответы [ 4 ]

4 голосов
/ 28 января 2011

При удалении элемента управления контейнера (такого как ваша форма) все его обработчики событий будут автоматически удалены и удалены.Эта очистка происходит для вас автоматически, поскольку ни пользовательский элемент управления, ни его контейнерная форма больше не существуют.

Единственный раз, когда вам действительно нужно беспокоиться о вызове RemoveHandler, это если вы подключаете обработчики событий к объектам, которыеожидается, что срок их службы значительно дольше, чем у их контейнеров.В этом случае возможно создать утечку памяти, потому что этот объект не может быть собран мусором, пока этот обработчик подписан.Вы можете прочитать более подробный пример здесь, в блоге Тесс Феррандез .Это не проблема, если оба объекта выходят из области видимости одновременно.

РЕДАКТИРОВАТЬ: Если вы все еще чувствуете, что вам абсолютно необходимо удалить обработчик (возможно, выобсессивно-компульсивный?), вы можете пойти дальше и сделать это в форме Dispose.Пурист может отказаться от использования IDisposable для чего-то подобного, но вы не увидите никаких плохих результатов.Вы действительно хотите убедиться, что вы не реализуете для этого метод Finalize.В этом нет никакого смысла: метод финализатора не будет вызываться до тех пор, пока не будет более сильных ссылок на объект, но единственный возможный вред в том, что он не вызовет RemoveHandler, состоит в том, что контейнер будет удерживатьссылка на этот объект дольше, чем необходимо.Вы обманываете себя, пытаясь удалить обработчики событий в методе Finalize.

Также имейте в виду, что на самом деле не имеет значения , где именно вы это делаете, потому что цельAddHandler / RemoveHandler - позволяет динамически добавлять и удалять обработчики событий .Вы можете вызывать их в любом месте вашего кода, который вы хотите.

1 голос
/ 28 января 2011

Предполагая, что ваша Форма является владельцем UserControl (ов), вам вообще не нужна очистка.

Если у вас были такие обработчики, как AddressOf OtherObject.Action1Performed, а OtherObject живет дольше, чем форма, то вам следует удалить обработчик.


Редактировать:

О месте': Не в Sub Finalize.

Вы можете использовать метод Dispose () (в C # вы можете переместить его из файла Designer).В противном случае используйте событие FormClosed.

Финализатор здесь не нужен, но он требует значительных затрат.

0 голосов
/ 01 февраля 2011

Финализатор объекта будет бесполезен для очистки подписок на события этого объекта.Он не сработает до тех пор, пока все издатели всех событий, на которые подписывается объект, сами не выйдут из области видимости, и как только это произойдет, вопрос очистки событий станет спорным.Создание финализатора для этой цели на самом деле будет контрпродуктивным, так как финализуемый объект будет задерживать сборку мусора как самого себя, так и любого объекта, на который он имеет прямую или косвенную ссылку.

Я бы посчитал это хорошей практикойубирать подписки на события как привычку.Хотя подписки на события можно рассматривать как управляемый ресурс, если издатель и подписчик имеют одинаковое время жизни, события из долгоживущих объектов являются неуправляемым ресурсом .Они должны быть очищены в Dispose, если они не очищены в другом месте (и Dispose должен быть «задним ходом» для очистки в другом месте).В то время как можно избежать игнорирования подписок на события для недолговечных объектов, такая практика требует определения того, какие издатели событий являются или могут быть долгоживущими.Также обратите внимание, что регулярная отмена подписки на события, когда объекты выходят за рамки, ограничит ущерб, который может быть причинен, если пропущено случайное событие.Если события от якобы недолговечных объектов отменяются, но событие одного долгоживущего объекта также отменяется, ни один из недолговечных объектов не может получить право на сборку мусора до тех пор, пока это делает долгоживущий объект.

0 голосов
/ 28 января 2011

не уверен, почему вы удаляете обработчики, если вы больше не нуждаетесь в них в следующем посте назад и не устанавливаете их снова при загрузке страницы, в противном случае, если вы используете их для каждого поста обратно, вы должны просто позволить GC обращаться с утилизацией

...