Hello! I am writing application which is server which communicates with client by socket. The server contains one form "frmMain" and one module "Module1". Module1 contains the following lines:
Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Module Module1
Public Const BS_PORT = 8221
Private pfnWorkerCallBack As AsyncCallback
Private soclistener As Socket
Private socWorker As Socket
Public Sub StartListening(ByVal Port As Integer)
Try
Dim ipLocal As IPEndPoint = New IPEndPoint(IPAddress.Any, Port)
soclistener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
soclistener.Bind(ipLocal)
soclistener.Listen(4)
soclistener.BeginAccept(New AsyncCallback(AddressOf OnClientConnect), Nothing)
Catch ex As Exception
End Try
End Sub
Private Sub OnClientConnect(ByVal asyn As IAsyncResult)
frmMain.rtbMessages.Text= “Client connected”
Try
socWorker = soclistener.EndAccept(asyn)
WaitForData(socWorker)
Catch ex As Exception
End Try
End Sub
Private Sub WaitForData(ByVal soc As Socket)
Try
Dim theSocPkt As CSocketPacket = New CSocketPacket()
If pfnWorkerCallBack Is Nothing Then
pfnWorkerCallBack = New AsyncCallback(AddressOf OnDataReceived)
End If
theSocPkt.thisSocket = soc
' now start to listen for any data...
soc.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, _
pfnWorkerCallBack, theSocPkt)
Catch ex As Exception
End Try
End Sub
Private Sub OnDataReceived(ByVal asyn As IAsyncResult)
Try
Dim theSockId As CSocketPacket = CType(asyn.AsyncState, CSocketPacket)
'end receive...
Dim iRx As Integer = 0
iRx = theSockId.thisSocket.EndReceive(asyn)
Dim chars As Char() = New Char(iRx) {}
Dim d As System.Text.Decoder = System.Text.Encoding.UTF8.GetDecoder()
Dim charLen As Integer = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0)
Dim szData As System.String = New System.String(chars)
'szData is the received data
rtbMessages.Text &= szData
WaitForData(socWorker)
Catch ex As Exception
End Try
End Sub
Private Class CSocketPacket
Public thisSocket As Socket
Public dataBuffer As Byte() = New Byte(0) {}
End Class
End Module
StartListening is called in frmMain_Shown. When I run this project and the client is connected to the application, the text in rtbMessages (RichTextBox in frmMain) is not changed. Where is the problem… I think that the problem Is with the threads but I don’t know how to solve it.
Thanks!

Unknown problem
Womble--
No. This is occuring in UpdateDisplayInMainFormsThread in line: Me.Invoke(...)
anandcbe14
Junmei
Private Sub OnDataReceived(ByVal asyn As IAsyncResult) is actually run in a different thread than the Form and RichTextBox are running.
You can solve this by creatng a delegate sub on the main form, it would look something like this:
'-----------------------------------------------------------------------------------------------
' Add to your form.
' Declare the Delegate.
private UpdateDisplayDelegate(ByVal message As String)
' Declare the method to handle the Delegate.
private Sub UpdateDisplay(ByVal message As String)
rtbMessages.SelectedText = message
rtbMessages.Refresh()
End Sub
' The public method called by Module1
public Sub UpdateDisplayInMainFormsThread(ByVal message as String)
Dim upd As New UpdateDisplayDelegate(AddressOf UpdateDisplay)
Me.Invoke(atd, New Object() {message})
'Me.Invoke causes the Delegate sub to be run
'in the Main Form's thread.
End Sub
'-----------------------------------------------------------------------------------------------
' Change in Module1
' All references to frmMain.rtbMessages.Text should be changed to...
frmMain.UpdateDisplayInMainFormsThread("Your message goes here.")
JavaBoy
etude
mta37
AboOmar
1. Put a button on your form [Start Listening] or something like that. Then move your code into the Button_OnClick method.
2. Put a 2 second timer that only runs once on your form that is started in your frmMain_Load method. Move your code into the Timer_Tick method.
MaryMary
Before invoking, try checking if Invoke is required (e.g. me.invokeRequired).
jiveshc
xr280xr
Then don't invoke
...set the properties directly.
Usually, a routine which needs to do something like this (update user interface objects on a different thread) the following pattern could be used:
delegate UpdateUICallback(<UI Parameters>)
Sub UpdateUI(<UI Parameters>)
if InvokeRequired then
d as new UpdateUICallback( addressof UpdateUI)
invoke(d, new object {<UI Parameters>})
else
<Use UI Parameters Directly>
end if
End sub
DHJr
That was the first thing that I've tried but it doesn't works :(