Stavros
Stavros

Reputation: 23

Multi-Thread (Append Text To TextBox)

Done my fair share of looking this up but it just doesn't make sense..

I know we have to use delegates to update a textbox thats on the Main UI.

Here is the code in the a nutshell:

Initiate the thread that will capture chats:

ChatQuery = New Thread(AddressOf FetchChats)
ChatQuery.Start()

FetchChats Code Simplified:

SetTextBoxWithInvoke(Form5.TextBox2, MESSAGE)

SetTextBoxWithInvokeCode:

Private Sub SetTextBoxWithInvoke(ByVal TB As TextBox, ByVal msg As String)
        If TB.InvokeRequired Then
            TB.Invoke(New AddToMessageBoxDelegate(AddressOf SetTextBoxWithInvoke), New Object() {TB, msg})
        Else
            TB.Text &= msg
        End If
    End Sub

The Problem?? Invoke is never required, and the new message is never appended to the textbox I need to be appended to.

Delegate:

Public Delegate Sub AddToMessageBoxDelegate(ByVal TB As TextBox, ByVal msg As String)

Upvotes: 0

Views: 223

Answers (1)

jmcilhinney
jmcilhinney

Reputation: 54457

The problem is that you're using the default instance of the form here:

SetTextBoxWithInvoke(Form5.TextBox2, MESSAGE)

Default instances are thread-specific so, if you execute that code on a background thread, rather than using the existing Form5 instance that was created and displayed on the UI thread, it will create a new instance on the current thread. There's no need to invoke a delegate to access that instance so InvokeRequired is always False.

You need to use the actual instance of Form5 that already exists. How exactly you do that depends on the circumstances. If the code that makes the call is already in that form then just use Me, which is implicit if you don't explicitly use another reference anyway. Otherwise, it's up to you to get the required reference into the required object to be used.

If the code is not in a form already then maybe you should not be doing it that way at all. Instead, you can use the SynchronizationContext class. You get the current instance when your object is created on the UI thread and you can then call its Send or Post method to marshal back to the UI thread without an explicit Control reference. That might not work in your case though, because you'd still need a reference to the correct TextBox.

Upvotes: 1

Related Questions