Hi,
Terry Olsen said:
I'm running an asynchronous Socket. In the ReceiveCallback method, I need
to append what is received to a textbox on the main form. I have this
code:
Private Sub ToChatWindow(ByVal msg As String)
txtChat.AppendText(msg)
End Sub
I've never used a delegate or invoke before and I'm rather confused on the
topic. Hope someone can help.
1) You first define a delegate, to understand delegates better, you have to
know the compiler creates a class that can wrap a sub or function with the
same signature for each delegate you define. Like other classes a delegate
can be used as a variable and can be instantiated, the constructor takes a
sub or function that matches the delegate signature. BUT, in VB.NET
AddressOf returns an instantiated delegate, so you don't need to explicitly
use the delegate's constructor.
2) When ToChatWindow is called, we check if InvokeRequired is needed (eg.
when you call from an other thread) and if it is needed, then we call
txtChat.Invoke which will invoke ToChatWindow again (through a delegate
instance), but this time it runs on the UI thread and InvokeRequired will be
false.
Public Class SomeForm
Inherits Form
' define delegate ( signature matches ToChatWindow )
Private Delegate Sub ToChatWindowHandler( msg As String )
' delegate instance
Private ToChatWindowHandlerInst As ToChatWindowHandler
Public Sub New()
' create delegate instance
ToChatWindowHandlerInst = AddressOf ToChatWindow
End Sub
Public Sub ToChatWindow( msg As String )
If ( txtChat.InvokeRequired ) Then
txtChat.Invoke( ToChatWindowHandlerInst, _
New Object() { msg } )
Return ' dont forget
End If
' at this point you are in UI thread
txtChat.AppendText( msg )
End Sub
End Class
Don't want to confuse you, but notice that you can also call
SomeDelegateInstance.Invoke(<parameters>), but this will just invoke the
wrapped function without marshalling it to the UI thread unlike
Control.Invoke(SomeDelegateInstance, <parameters>) which does marshall to
the UI thread(which is the thread that created the Control).
And one more thing, there is Control.Invoke and Control.InvokeLater, the
former will wait until the function has run on the UI thread, the latter
will not wait until it is run and return immediately.
HTH,
Greetings