Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

vb.net - Update UI form from worker thread

I am new to multi-threading in VB.NET and have come across a problem whereby I am wanting to append text to a text box on a form from a service thread running in the background.

The application I am developing is a client/server listener, I have been able to get the client and server PC's to talk with each other (confirmed through MsgBox), however I am now struggling to get the service thread on the server to append the text to the textbox, nothing vissible occurs.

I have a form named testDebug which calls a class (RemoteSupport), this class does all the handshake tasks and updates the textbox with the connection data.

Can anyone identify where I am going wrong and point me in the right direction?

The following is the code I have: The form has a textbox named txtOutput, the following is from the remoteSupport class

Dim outMessage As String = (encoder.GetString(message, 0, bytesRead))
 MsgBox(outMessage, MsgBoxStyle.Information, "MEssage Received")
  If outMessage IsNot Nothing Then
    If testDebug.InvokeRequired Then
        ' have the UI thread call this method for us
        testDebug.Invoke(New UpdateUIDelegate(AddressOf HandleClientComm), New Object() {outMessage})    '
    Else
       testDebug.txtOutput.AppendText(outMessage)
    End If

    'RaiseEvent MessageReceived(outMessage) // a previous attempt to use custom events
 End If

I am not sure if the invoke method is the ideal solution or if custom events are, I have spent some time on trying to get custom events to work, but these didnt work either.

 // In the RemoteSupport class
 Public Delegate Sub MessageReceivedHandler(ByVal message As String)
 Public Shared Event MessageReceived As MessageReceivedHandler

// Located throughout the RemoteSupport class where debug information is required.
RaiseEvent MessageReceived(outMessage)

// Located in the code-behind of the form
Private Sub Message_Received(ByVal message As String)
testDebugOutput(message) // this is a function I have created 
                         // to append the text to the text box
End Sub

The code supplied has been cut down so if there is anything else that you want to see or any questions please let me know.

Thanks for your assistance.

EDIT: I have uploaded the two VB files (form and class) to my site, I would appreciate it if someone could have a look at it to help me with identifying the problem with the UI not updating.

I have tried a few other things but nothing seems to be updating the UI once the worker thread has started.

Form: mulholland.it/testDebug.vb.txt Class: mulholland.it/remoteSupport.vb.txt

Thanks for your assistance.

Matt

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have a form named testDebug...

If testDebug.InvokeRequired Then

This is a classic trap in VB.NET programming. Set a breakpoint on the If statement. Notice how it returns False, even though you know that the code is running on another thread?

InvokeRequired is an instance property of a Form. But testDebug is a class name, not a reference to an instance of a form of type testDebug. That this is possible in VB.NET has gotten a lot of VB.NET programmers in deep trouble. It is an anachronism carried over from VB6. It completely falls apart and blows up in your face when you do this in a thread. You'll get a new instance of the form, instead of the one that the user is looking at. One that isn't visible because its Show() was never called. And otherwise dead as a doornail since the thread isn't running a message loop.

I answered this question several times already, with the recommended fix. I'll just refer you to them rather than rehashing it here:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...