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


Практическое руководство. Объявление настраиваемых событий для предотвращения блокировки (Visual Basic)

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

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

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

Пример

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

Когда код генерирует 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

См. также