AddHandler / RemoveHandler неправильно утилизируются - PullRequest
3 голосов
/ 30 сентября 2008

Использование метода AddHandler, если я никогда не использую RemoveHandler, приведет ли это к утечкам памяти в некоторых условиях и ситуациях? Я не уверен в истинности этого.

И есть ли другие причины утечек памяти, которые доступны только в VB, в отличие от C #?

Ответы [ 2 ]

11 голосов
/ 30 сентября 2008

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

Итак, возьмем, к примеру, случай, когда вы порождаете дочернюю форму, и форма подписывается на событие кнопки Click на форме.

button1.Click += new EventHandler(Form_Click_Handler);

Теперь объект кнопки будет держаться за ссылку на форму. Когда форма закрыта / удалена / установлена ​​в нуль, форма и кнопка больше не нужны; память исправлена.

Проблема возникает, когда у вас есть глобальная структура или объект, у которого больше время жизни. Допустим, объект Application поддерживает список открытых дочерних окон. Таким образом, каждый раз, когда создается дочерняя форма, объект приложения подписывается на событие Form, чтобы он мог следить за ним. В этом случае, даже если форма закрыта / удалена, объект приложения поддерживает ее работу (объект без мусора содержит ссылку на форму) и не позволяет восстановить ее память. По мере того, как вы продолжаете создавать и закрывать окна, у вас возникает утечка, когда ваше приложение занимает все больше и больше памяти. Следовательно, вам нужно явно отказаться от подписки, чтобы удалить ссылку на форму из приложения.

childForm.Event -= new EventHandler(Form_Handler)

Поэтому рекомендуется иметь блок отмены подписки (- =), дополняющий подпрограмму подписки (+ =) ... однако вы можете обойтись без нее для стандартных сценариев.

0 голосов
/ 30 сентября 2008

Если объект a связан с событием объекта b, то объект b не будет собран до тех пор, пока объект a не будет собран.

Приостановка события считается ссылкой на объект издателя.

И да, это также происходит на C #, я не имею ничего общего с языком.

...