方法 : ブロックを回避するイベントを宣言する
更新 : 2007 年 11 月
イベント ハンドラが後続のイベント ハンドラをブロックしないことが重視される状況があります。カスタム イベントを使うと、イベントから自身のイベント ハンドラを非同期に呼び出すことができます。
既定では、イベント宣言のバッキング ストア フィールドは、すべてのイベント ハンドラが連続的に結合されたマルチキャスト デリゲートです。つまり、実行の完了に時間がかかるハンドラがあると、それが完了するまで他のハンドラはブロックされます。(実行に時間がかかったり、操作をブロックする可能性があったりするイベント ハンドラは、設計を見直すことをお勧めします。)
Visual Basic に用意された既定のイベント実装を使う代わりに、カスタム イベントを使うと、イベント ハンドラを非同期に実行できます。
使用例
次のコード例では、AddHandler アクセッサによって、Click イベントの各ハンドラのデリゲートが EventHandlerList フィールドに格納されている 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