Solarplex
Solarplex

Reputation: 107

Set Label From Thread

Form1.vb

Imports System.Threading

Public Class Form1

Dim demoThread As Thread

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim Start As New Class1
    Me.demoThread = New Thread( _
            New ThreadStart(AddressOf Start.ThreadProcSafe))

    Me.demoThread.Start()

End Sub
Delegate Sub SetTextCallback([text] As String)
Public Sub SetText(ByVal [text] As String)

    ' InvokeRequired required compares the thread ID of the 
    ' calling thread to the thread ID of the creating thread. 
    ' If these threads are different, it returns true. 
    If Me.textBox1.InvokeRequired Then
        Dim d As New SetTextCallback(AddressOf SetText)
        Me.Invoke(d, New Object() {[text]})
    Else
        Me.textBox1.Text = [text]
    End If
End Sub
End Class

Class1.vb

Public Class Class1

Public Sub ThreadProcSafe()
    Form1.SetText("This text was set safely.")
End Sub
End Class

Can someone tell me why this doesn't update the textbox?

It works when ThreadProcSafe is called when its inside Form1(and is still started by a thread) but when it's moved outside of the class into another, no warnings or errors but doesn't update.

Upvotes: 1

Views: 467

Answers (1)

jmcilhinney
jmcilhinney

Reputation: 54417

The reason is that you are referring to the default instance in your second code snippet. Default instances are thread-specific so that second code snippet will create a new instance of the Form1 type rather then use the existing instance. Your Class1 needs a reference to the original instance of Form1.

If that's not practical then the solution is to not do the delegation in the form but rather do it in the class accessing the form, using the SynchronizationContext class.

Upvotes: 2

Related Questions