0

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.

hexcode
  • 393
  • 1
  • 4
  • 13

2 Answers2

1

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#?

Community
  • 1
  • 1
Jim
  • 6,753
  • 12
  • 44
  • 72
  • I'll try to turn this in vb.net. I'll be back in case it works! – hexcode Sep 18 '15 at 05:18
  • I made the server to raise an event upon reception of data. I them updated the listview through the eventhandler. It worked! Thank you for the article, it helped me learn something, too! – hexcode Sep 18 '15 at 05:35
0

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
NoAlias
  • 9,218
  • 2
  • 27
  • 46
  • This isn't working for me. I did the exact same thing. The listview's still not being updated. Any idea why ? – hexcode Sep 18 '15 at 05:18
  • I made the server to raise an event upon reception of data. I them updated the listview through the eventhandler. It worked! Thank you for the suggestion! – hexcode Sep 18 '15 at 05:35