Synchronous Delegate in VB.NET

I didn’t know why I would need one either until the need came up (“Oh no, my UI is on a different thread!”). Delegates are described as similar to function pointers in C++ in the Microsoft documentation. When I read that I said to myself “yeah, but Visual Basic doesn’t work like that wonderful and painfully frustrating language that AT&T invented so long ago”. So Microsoft still has to learn that Chinese is painful if you’re not from China. I’m discovering in the new VB, it does kinda work like that – a little.

In my case I had a shared class and a form that were working together. My class raised an event that was handled on the form to update a control on the form. The event also had parameters that were passed with the event to the event handler on the form. When the handler was invoked I received an exception that stated the control I was accessing was on another thread. I didn’t have to deal with this in the old VB under ‘normal’ circumstances. If I did I would have to be the C++ programmer working in VB – and that would have been considered a work around at best. So this is vast new territory for me, and I apologize ahead of time if something isn’t perfect. And yes, its a Windows Forms project with no XAML.

So… How To

Conceptually, you have to create a Delegate (a function pointer in C++) for your method (yeah, the one that updates the control) that gets used (dereferenced and called) by the user control Invoke method which invokes the method (yeah, that one) on its thread. On an aside, don’t ask why I think Microsoft put a C++ programmer in charge of Visual Basic NET. However, I’m taking the bad with the good here – the new Thread way is really powerful in my opinion. I just really would have preferred this kind of ‘icky’ stuff to be abstracted away. I guess you can’t have that multi-thread evil at Microsoft with VB without a bit of ‘ick’. In other words, I can’t help but to be critical; it’s still kind of ‘hakish’ if you ask me.

OK, as I stated earlier, the event was handled on a form to update a control on the form. The first thing to do is to declare a Delegate at the top after the opening of the form class. The declaration is similar to an interface declaration in that there is no body to the declaration, just the function (or method) signature. Name the Delegate something like controlUpdateDelegate. Now go and code the controlUpdate method, which should be easy considering its probably the same code you wrote in your original handler. Now, in the original event handler, you’ll need to start an If block that tests for the control you’re updating InvokeRequired property (no autocomplete from the IDE unfortunately). If that boolean is true you have to create a New Delegate (updateControlDelegate) with the AddressOf the function you wrote to update the control (controlUpdate). After that you have to call that controls (the one you’re updating) Invoke method with the Delegate you created and the parameters you originally sent to the event handler. If that InvokeRequired boolean is false just call that method you created.

That’s it – that’s what worked for me.

Some Example Code Structure

' on the form is someControlPublic 
Class someForm
 Public Delegate Sub controlUpdateDelegate(someParam as String) 

 Public Sub New()
   AddHandler someClass.coolEvent, AddressOf  coolEventHappened
 End Sub

 Private Sub coolEventHappened(someParam As String)
   If someControl.InvokeRequired Then
     Dim del = New controlUpdateDelegate(AddressOf controlUpdate)
     someControl.Invoke(del, someParam)
   End If
 End Sub

 Private Sub controlUpdate(someParam As String)
 ' update someControl here with someParam
 End Sub
End Class

Public Class someClass
  Public Shared Event coolEvent(someParam As String) 

  Public Shared Sub doSomethingCool() 
    RaiseEvent coolEvent("Cool!") 
  End Sub

End Class.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s