ПрограммированиеWinForms-разработчик, программист интерфейсов VB.NET

Как реализуется событийно-ориентированное взаимодействие между формами и контролами в WinForms-проектах Visual Basic? Опишите механизм подписки и отписки от событий, возможные ловушки и способы их предотвращения.

Проходите собеседования с ИИ помощником Hintsage

Ответ

В WinForms события реализуются через делегаты (Event) и специальные синтаксические конструкции Visual Basic — AddHandler и RemoveHandler.

  • Подписка на событие: выполняется оператором AddHandler.
  • Отписка от события: выполняется с помощью RemoveHandler, важно всегда точно совпадать с адресуемым обработчиком.
  • Контролы могут иметь несколько подписчиков на одно событие.

Пример:

AddHandler Button1.Click, AddressOf Button1_Click Sub Button1_Click(sender As Object, e As EventArgs) MessageBox.Show("Нажата кнопка!") End Sub ' Для отписки: RemoveHandler Button1.Click, AddressOf Button1_Click

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

Вопрос с подвохом

В: Что произойдет, если забыть вызвать RemoveHandler при уничтожении объекта-подписчика на событие?

О: Если объект подписан на событие у другого объекта и не был отписан (RemoveHandler), то garbage collector не сможет освободить память под подписчика, так как будет сохраняться жёсткая ссылка через делегат события. Это приведёт к утечке памяти.


История

1. В ПО для учета заявок объект журнала подписывался на события всех динамически создаваемых форм. После закрытия форм не вызывался RemoveHandler, в результате со временем по мере работы приложения увеличивалось потребление памяти — объекты висели в памяти до закрытия всей программы.


История

2. В образовательном проекте забыли отписать обработчик события при повторном открытии дочерней формы. В результате при каждом открытии событие срабатывало по нескольку раз (каждый раз добавлялся новый подписчик), что вызывало каскад дублированных действий и путаницу в логике интерфейса.


История

3. На промышленных панелях оператора инспектор запустил автоматическое тестирование, которое подписывает обработчик на событие таймера. После каждого теста объект создавался заново, но подписка не снималась, что приводило к постепенному замедлению, доказывая критическую важность RemoveHandler при использовании событий.