Reputation: 403
I've got a listview control on the main form. I've also got a webserver running. Here's the webserver class's relevant code:
Public Function start(ipAddress As IPAddress, port As Integer, maxNOfCon As Integer, contentPath As String) As Boolean
If running Then
Return False
End If
Try
serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
serverSocket.Bind(New IPEndPoint(ipAddress, port))
serverSocket.Listen(maxNOfCon)
serverSocket.ReceiveTimeout = timeout
serverSocket.SendTimeout = timeout
running = True
Me.contentPath = contentPath
Catch
Return False
End Try
Dim requestListenerT As New Thread(AddressOf first)
requestListenerT.Start()
Return True
End Function
Function second(clientSocket As Socket)
'clientSocket.ReceiveTimeout = timeout
'clientSocket.SendTimeout = timeout
End Function
Function first()
While running
Dim clientSocket As Socket
Try
clientSocket = serverSocket.Accept()
Dim requestHandler As New Thread(AddressOf second)
Try
handleTheRequest(clientSocket)
Catch
Try
clientSocket.Close()
Catch
End Try
End Try
requestHandler.Start()
Catch
End Try
End While
End Function
The problem is, the code inside the function handleTheRequest doesn't update the listview control on the form.
Private Sub handleTheRequest(clientSocket As Socket)
'...
'if xxx data comes in then frm_Main.lstview.items.add(xxxx)
end sub
Could you tell me why this is happening? I suspect it's got something to do with the fact that I'm using threads.
Upvotes: 0
Views: 232
Reputation: 9193
Use the Invoke Method to execute code on the thread that owns the ListView control. You must do this to ensure thread safety. It is possible to create an inconsistent state of the control, encounter race conditions, or have deadlocks, if multiple threads are manipulating the UI, which is why .Net throws an InvalidOperationException if you try. Sure you could use lstview.CheckForIllegalCrossThreadCalls = False
, but you'll regret it when you do a release build as the Exception will be thrown again.
Private Sub handleTheRequest(clientSocket As Socket)
frm_Main.lstview.Invoke(Sub()
frm_Main.lstview.Items.Add("Some Data")
End Sub)
End Sub
Upvotes: 0
Reputation: 6881
You cannot directly modify the UI except from the main thread. The way to do this is to register a callback method (aka a delegate).
Here's another SO post that specifically answers how to do that, although the answer is for C#, it is the same approach for vb just a bit different syntax.
How to update the GUI from another thread in C#?
Upvotes: 1