VB.Net Cross Thread Events in WinForms
Today I quickly did a proof of concept on integrating a third part component into a winforms application and had to figure out how to raise events on the Windows Forms UI thread from a different one. There are plenty of examples of doing this in C# but they didn't quite translate to VB.Net.
Although a BackgroundWorker may have worked I had some more complex requirements. Therefore I slightly tweaked a C# cross thread example on stackoverflow and combined it with another example of building a custom event. Here is what I came out with. I have to investigate better ways of doing this but since there is a lack of any VB.Net examples I thought I would post one.
And here is an example of using it on a Windows Form where a label gets updated with values divisible by 10.
Although a BackgroundWorker may have worked I had some more complex requirements. Therefore I slightly tweaked a C# cross thread example on stackoverflow and combined it with another example of building a custom event. Here is what I came out with. I have to investigate better ways of doing this but since there is a lack of any VB.Net examples I thought I would post one.
Imports System.ComponentModel
Imports System.Threading
Public Class CrossThreadingExample
Private dummyThread As Thread
Private ReadOnly crossThreadEventList As New List(Of CrossThreadEventHandler)
Public Delegate Sub CrossThreadEventHandler(sender As Object, e As CrossThreadEventArgs)
Public Custom Event CrossThreadNotification As CrossThreadEventHandler
AddHandler(handler As CrossThreadEventHandler)
Me.crossThreadEventList.Add(handler)
End AddHandler
RemoveHandler(handler As CrossThreadEventHandler)
Me.crossThreadEventList.Remove(handler)
End RemoveHandler
RaiseEvent(sender As Object, e As CrossThreadEventArgs)
For Each del In Me.crossThreadEventList
Dim synchronizedInvoke As ISynchronizeInvoke = DirectCast(del.Target, ISynchronizeInvoke)
If synchronizedInvoke IsNot Nothing AndAlso synchronizedInvoke.InvokeRequired Then
synchronizedInvoke.Invoke(del, New Object() {sender, e})
Else
del.DynamicInvoke(New Object() {sender, e})
End If
Next
End RaiseEvent
End Event
Public Sub Start()
Me.dummyThread = New Thread(AddressOf DoWork)
Me.dummyThread.IsBackground = True
Me.dummyThread.Start()
End Sub
Public Sub Cancel()
Me.dummyThread.Abort()
End Sub
Private Sub DoWork()
Dim i As Integer = 0
While i < Integer.MaxValue
i += 1
If i Mod 10 = 0 Then
RaiseEvent CrossThreadNotification(Me, New CrossThreadEventArgs(i))
End If
Thread.Sleep(100)
End While
End Sub
End Class
Public Class CrossThreadEventArgs
Inherits EventArgs
Public Property NumberDivisibleBy10 As Integer
Public Sub New(number As Integer)
MyBase.New()
Me.NumberDivisibleBy10 = number
End Sub
End Class
And here is an example of using it on a Windows Form where a label gets updated with values divisible by 10.
Public Class ExampleForm
Private WithEvents crossThreadingExample As CrossThreadingExample
Public Sub New()
Me.InitializeComponent()
Me.crossThreadingExample = New CrossThreadingExample()
Me.crossThreadingExample.Start()
End Sub
Public Sub ChangeLabel(sender As Object, e As CrossThreadEventArgs) Handles crossThreadingExample.CrossThreadNotification
Me.LabelCounter.Text = e.NumberDivisibleBy10.ToString()
End Sub
Protected Overrides Sub OnClosing(e As System.ComponentModel.CancelEventArgs)
MyBase.OnClosing(e)
Me.crossThreadingExample.Cancel()
End Sub
End Class
Comments
Post a Comment