Поделиться через


Практическое руководство. Объявление события, исключающего блокирование

Обновлен: Ноябрь 2007

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

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

Вместо использования реализации событий, которую Visual Basic предоставляет по умолчанию, можно использовать пользовательское событие для запуска обработчиков событий в асинхронном режиме.

Пример

В этом примере метод доступа AddHandler добавляет делегат для каждого обработчика событийClick для ArrayList, хранящегося в поле EventHandlerList.

Когда код вызывает событие Click, метод доступа RaiseEvent вызывает все делегаты обработчика события, асинхронно используя метод BeginInvoke. Этот метод вызывает каждый обработчик на рабочем потоке и немедленно возвращает, чтобы обработчики не могли блокировать друг с друга.

Public NotInheritable Class ReliabilityOptimizedControl
    'Defines a list for storing the delegates
    Private EventHandlerList As New ArrayList

    'Defines the Click event using the custom event syntax.
    'The RaiseEvent always invokes the delegates asynchronously
    Public Custom Event Click As EventHandler
        AddHandler(ByVal value As EventHandler)
            EventHandlerList.Add(value)
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            EventHandlerList.Remove(value)
        End RemoveHandler
        RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
            For Each handler As EventHandler In EventHandlerList
                If handler IsNot Nothing Then
                    handler.BeginInvoke(sender, e, Nothing, Nothing)
                End If
            Next
        End RaiseEvent
    End Event
End Class

См. также

Задачи

Практическое руководство. Объявление событий, которые экономят использование памяти

Ссылки

Оператор Event

ArrayList

BeginInvoke