Porady: deklarowanie zdarzeń niestandardowych w celu unikania blokowania (Visual Basic)
Istnieje kilka sytuacji, w których ważne jest, aby jedna procedura obsługi zdarzeń nie blokowała kolejnych programów obsługi zdarzeń. Zdarzenia niestandardowe umożliwiają asynchroniczne wywoływanie przez zdarzenie procedur obsługi zdarzeń.
Domyślnie pole magazynu kopii zapasowych dla deklaracji zdarzenia jest delegatem multiemisji, który szeregowo łączy wszystkie programy obsługi zdarzeń. Oznacza to, że jeśli ukończenie jednej procedury obsługi zajmuje dużo czasu, spowoduje to zablokowanie pozostałych procedur obsługi do momentu jego ukończenia. (Dobrze zachowywane programy obsługi zdarzeń nigdy nie powinny wykonywać długotrwałych lub potencjalnie blokujących operacji).
Zamiast używać domyślnej implementacji zdarzeń zapewnianych przez program Visual Basic, można użyć zdarzenia niestandardowego do asynchronicznego wykonywania procedur obsługi zdarzeń.
Przykład
W tym przykładzie akcesorium AddHandler
dodaje delegata dla każdego programu obsługi Click
zdarzenia do ArrayList obiektu przechowywanego EventHandlerList
w polu.
Gdy kod zgłasza Click
zdarzenie, RaiseEvent
metoda dostępu wywołuje wszystkie delegaty programu obsługi zdarzeń asynchronicznie przy użyciu BeginInvoke metody . Ta metoda wywołuje każdą procedurę obsługi w wątku procesu roboczego i zwraca ją natychmiast, więc programy obsługi nie mogą blokować się nawzajem.
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