How can I make a event raise and update controls on a form from an asynchronous socket ?
-
Hi All, First off all, I want to THANK everyone on this site for whatever contribution they delivered. As a starting Developer ( used-to-be sysadmin) I can't even count anymore how many articles here i've read which helped me out A LOT. But now. i'm stuck... I've written an application using an ASync SocketClient which communicates with a server. Now that it has become clear that several applications should communicate with the same TCP server using same protocol and logic, i wanted to pull the socketclient from the app, built a dll from it and "voila".. however, I'm having a problem with Cross-Thread errors.. What i've done: My Dll
Public Class NoctrisClient
Public Event ClientConnected()
Public Delegate Sub SimpleCallBack()
Public isConnected as boolean = falsePrivate endpoint as new IPEndPoint(system.net.dns.GetHostEntry("my.server.com").addresslist(0),1234)
Private SocketClient as SocketPublic Sub New()
me.connect()
End sub
Public sub Connect()ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
ClientSocket.BeginConnect(endpoint, AddressOf Connected, Nothing)end sub
Private Sub Connected(ByVal ar As IAsyncResult)
Try
ClientSocket.EndConnect(ar)
'-- Ok, we are connected
EventClientConnected()
'-- Start Receiving Data
ClientSocket.BeginReceive(RecvBuffer, 0, RecvBuffer.Length, _
SocketFlags.None, AddressOf ReceivedData, Nothing)Catch ex As Exception '-- Call DisconnectedUI ' Make call to raise ClientDisconnectedEvent
' EventClientDisconnected()
End Try
End Sub'... and so on.. all code from the socketclient is ok..it worked before so...
Private Sub RaiseClientConnected()
RaiseEvent ClientConnected()
isConnected = True
End SubPrivate Sub EventClientConnected()
' Doing this here because i call these events on several places and did not wanted to keep repeating code.
Dim cb As New SimpleCallback(AddressOf RaiseClientConnected)
cb.Invoke()
End Subend class
So this, in a VERY short nutshell, is the socketclient component.. So far, so good.. the events are raised as they should... But ... Then the form does something like this:
imports my.namepace.NoctrisClient
Public Class Myform
Private WithEvents Client as new NoctrisClient
Private Delegate Sub SimpleCallBack()Private Sub Han
-
Hi All, First off all, I want to THANK everyone on this site for whatever contribution they delivered. As a starting Developer ( used-to-be sysadmin) I can't even count anymore how many articles here i've read which helped me out A LOT. But now. i'm stuck... I've written an application using an ASync SocketClient which communicates with a server. Now that it has become clear that several applications should communicate with the same TCP server using same protocol and logic, i wanted to pull the socketclient from the app, built a dll from it and "voila".. however, I'm having a problem with Cross-Thread errors.. What i've done: My Dll
Public Class NoctrisClient
Public Event ClientConnected()
Public Delegate Sub SimpleCallBack()
Public isConnected as boolean = falsePrivate endpoint as new IPEndPoint(system.net.dns.GetHostEntry("my.server.com").addresslist(0),1234)
Private SocketClient as SocketPublic Sub New()
me.connect()
End sub
Public sub Connect()ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
ClientSocket.BeginConnect(endpoint, AddressOf Connected, Nothing)end sub
Private Sub Connected(ByVal ar As IAsyncResult)
Try
ClientSocket.EndConnect(ar)
'-- Ok, we are connected
EventClientConnected()
'-- Start Receiving Data
ClientSocket.BeginReceive(RecvBuffer, 0, RecvBuffer.Length, _
SocketFlags.None, AddressOf ReceivedData, Nothing)Catch ex As Exception '-- Call DisconnectedUI ' Make call to raise ClientDisconnectedEvent
' EventClientDisconnected()
End Try
End Sub'... and so on.. all code from the socketclient is ok..it worked before so...
Private Sub RaiseClientConnected()
RaiseEvent ClientConnected()
isConnected = True
End SubPrivate Sub EventClientConnected()
' Doing this here because i call these events on several places and did not wanted to keep repeating code.
Dim cb As New SimpleCallback(AddressOf RaiseClientConnected)
cb.Invoke()
End Subend class
So this, in a VERY short nutshell, is the socketclient component.. So far, so good.. the events are raised as they should... But ... Then the form does something like this:
imports my.namepace.NoctrisClient
Public Class Myform
Private WithEvents Client as new NoctrisClient
Private Delegate Sub SimpleCallBack()Private Sub Han
controls are only available on the main thread(where all presentation takes place). since you are on a different thread it complains when you try to use something on the main thread without getting on that thread. you need to use the INVOKE command of the control that will place the assignment of the text property on the main thread. to do this, you will need to use a DELEGATE which will need the same signature that the routine has that will contain the invoke call... this idea is like this define the delegate in your routine change to this
Public Sub ConnectedUi()
if LblServerStatus.InvokeRequired Then
LblServerStatus.Invoke(....) 'new instance of the delegate pointing to this routine
Exit Sub
End If
LblServerStatus.Text = "Connected"
End Sub'Never argue with an idiot; they'll drag you down to their level and beat you with experience.' ~ anonymous 'Life's real failure is when you do not realize how close you were to success when you gave up.' ~ anonymous