Safely receiving events from a stream
I'm having problems with events fired from a non-UI thread in that I don't want to handle If me.invokerequired for every event handler added to the thread in Form1.
I'm sure I read somewhere how to use a delegate event (on SO), but I can't find it.
Public Class Form1
Private WithEvents _to As New ThreadedOperation
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button.Click
_to.start()
End Sub
Private Sub _to_SomthingHappend(ByVal result As Integer) Handles _to.SomthingHappend
TextBox.Text = result.ToString //cross thread exception here
End Sub
End Class
Public Class ThreadedOperation
Public Event SomthingHappend(ByVal result As Integer)
Private _thread As Threading.Thread
Public Sub start()
If _thread Is Nothing Then
_thread = New Threading.Thread(AddressOf Work)
End If
_thread.Start()
End Sub
Private Sub Work()
For i As Integer = 0 To 10
RaiseEvent SomthingHappend(i)
Threading.Thread.Sleep(500)
Next
End Sub
End Class
source to share
You got your class from Control. A bit unusual, but if the control is actually hosted on a form, you can use Me.Invoke () to marshal the call. For example:
Private Delegate Sub SomethingHappenedDelegate(ByVal result As Integer)
Private Sub Work()
For i As Integer = 0 To 10
Me.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)
Threading.Thread.Sleep(500)
Next
End Sub
Private Sub SomethingHappenedThreadSafe(ByVal result As Integer)
RaiseEvent SomthingHappend(result)
End Sub
If that class object is not actually hosted on the form, you need to pass a reference to the form so that it can call Invoke ():
Private mHost As Form
Public Sub New(ByVal host As Form)
mHost = host
End Sub
and use mHost.Invoke (). Or BeginInvoke ().
The last trick in the book is to use your main launch form as a sync object. This is not entirely safe, but it works 99% of the time:
Dim main As Form = Application.OpenForms(0)
main.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)
Please be aware that there is a bug in WF that prevents OpenForms () from accurately tracking open forms when dynamically recreating them.
source to share