Asynchronous Event Delegation

[vb.net]I was playing around with delegates today and came up with a quick example of how to fire events using delegates in an asynchronous manner (fire an event and continue processing).

Revised Code (Original at bottom):

Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
'JUST ADD A STANDARD BUTTON TO YOUR FORM
#End
Region
'
'Create instance of class
'
Friend oDelClass As New DelClass

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      '
      'Add a handler for the event. Could also be done WithEvents .
      '
      AddHandler oDelClass.DoneProcessing, AddressOf dosomething
End
Sub

Public
Sub dosomething(ByVal sender As Object, ByVal e As System.EventArgs)
      MsgBox("I've been shown from a new thread pool thread!")
End
Sub

Private
Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      '
      'Call procedure that will raise an event when done.
      '
      oDelClass.ProcessSomething()
End
Sub

End
Class

Class Form1
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
'JUST ADD A STANDARD BUTTON TO YOUR FORM
#End
Region
'
'Create instance of class
'
Friend oDelClass As New DelClass

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      '
      'Add a handler for the event. Could also be done WithEvents .
      '
      AddHandler oDelClass.DoneProcessing, AddressOf dosomething
End
Sub

Public
Sub dosomething(ByVal sender As Object, ByVal e As System.EventArgs)
      MsgBox("I've been shown from a new thread pool thread!")
End
Sub

Private
Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      '
      'Call procedure that will raise an event when done.
      '
      oDelClass.ProcessSomething()
End
Sub

End
Class

Public Class DelClass
'
'Delegate (function pointer)
'
Friend Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
'
'Instance of the function pointer that points to OnDoneProcessing.
'
Private MyEventInvoker As New MyEventHandler(AddressOf OnDoneProcessing)
'
'Event declaration where MyEventHandler is simply an interface.
'Could be: Friend MyEvent(byval sender as object, byval e as system.eventargs)
'
Friend Event DoneProcessing As MyEventHandler
'
'Overidable event calling procedure.. standard .NET event design
'
Friend Overridable Sub OnDoneProcessing(ByVal sender As Object, ByVal e As System.EventArgs)
      '
      'If OnDoneProcessing was called using BeginInvoke, then you are already running in a thread
      'pool thread parallel to the caller thread (async).
      '
      'Fire the event
      '
      RaiseEvent DoneProcessing(sender, e)
End
Sub

Friend Sub ProcessSomething()
      '
      'Perform some processing that in return raises an event...
      '
      'Calls OnDoneProcessing, which raises the event, in a new thread.
      '
      Call MyEventInvoker.BeginInvoke(New Object, New System.EventArgs, Nothing, Nothing)
      '
      'You could also use a function, then use EndInvoke, or a callback, to get the return.
      'That is beyond the needs of this example, but here is a link:
      'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconasynchronousdelegatesprogrammingsample.asp?frame=true
      '
End
Sub

End
Class

Class DelClass
'
'Delegate (function pointer)
'
Friend Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
'
'Instance of the function pointer that points to OnDoneProcessing.
'
Private MyEventInvoker As New MyEventHandler(AddressOf OnDoneProcessing)
'
'Event declaration where MyEventHandler is simply an interface.
'Could be: Friend MyEvent(byval sender as object, byval e as system.eventargs)
'
Friend Event DoneProcessing As MyEventHandler
'
'Overidable event calling procedure.. standard .NET event design
'
Friend Overridable Sub OnDoneProcessing(ByVal sender As Object, ByVal e As System.EventArgs)
      '
      'If OnDoneProcessing was called using BeginInvoke, then you are already running in a thread
      'pool thread parallel to the caller thread (async).
      '
      'Fire the event
      '
      RaiseEvent DoneProcessing(sender, e)
End
Sub

Friend Sub ProcessSomething()
      '
      'Perform some processing that in return raises an event...
      '
      'Calls OnDoneProcessing, which raises the event, in a new thread.
      '
      Call MyEventInvoker.BeginInvoke(New Object, New System.EventArgs, Nothing, Nothing)
      '
      'You could also use a function, then use EndInvoke, or a callback, to get the return.
      'That is beyond the needs of this example, but here is a link:
      'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconasynchronousdelegatesprogrammingsample.asp?frame=true
      '
End
Sub

End
Class

James made an excellent blog that inherits from a button and mirrors the standard click event with an ASync version. This design is very flexible, and suitable for use with any inheritable class that has events.

No Comments