hexcode
hexcode

Reputation: 403

Listview not updating entries when called from a different thread from inside a webserver class

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

Answers (2)

NoAlias
NoAlias

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

Jim
Jim

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

Related Questions