Question Impossible to update a TextBox when running a thread from a Class

freda217

New member
Joined
Sep 15, 2011
Messages
3
Programming Experience
1-3
Hello,

I am having trouble accessing the main thread (my form) when calling thread is running in a class (or module).

I have no problem to manipulate a data (in a thread) from a form, the textbox can be updated using delegate and invokerequired but it doesn't seem as easy when the thread that processes a variable is handled by a thread that is running in a class.

To simplify my application: I created a new application:
one form called Form1,
one class called classvar,
inside the form:
-Textbox1: to display a value.
-Button1: to trigger the thread.

The code is:

-------for the form--------
Imports System.Threading
Public Class Form1
   
    Public Thread1 As Thread = Nothing
    Public Delegate Sub settextcallback(ByVal value As Integer)
   
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim classvarinst As New Classvar
        ' New ThreadStart(AddressOf classvarinst.run))
        Me.Thread1 = New Thread( _
        New ThreadStart(AddressOf runtest))
        Thread1.Name = "Thread1 run"
        Me.Thread1.Start()
    End Sub
 
    Private Sub runtest()
        Dim classvarinst As New Classvar
        classvarinst.run()
    End Sub
 
    Public Sub SetText(ByVal value As Integer)
        ' 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() {[value]})
        Else
            TextBox1.Text = value
        End If
    End Sub

----------------------------

------- for the class---------
Imports System.Threading
Public Class Classvar
 
    Public Sub run()
        Dim i As Integer
        Dim form1inst As New Form1
        i = 0
        Do While True
            i = i + 1
            If i = 10000 Then
                i = 0
            End If
 
            Thread.Sleep(1000)
 
            Form1inst.SetText(i)
        Loop
    End Sub
 
End Class

----------

The textbox is never updated. It should be incremented by 1 every seconds.

Using debug (display threads), after calling Thread1 it seems impossible to access the main thread again.
Me.TextBox1.InvokeRequired returns false!!!! It should be True because the calling and creating thread are different.

Please help! I have been stuck on this problem for dayssss.

Many thanks in advance.

Cheers,

Fred
 
Last edited by a moderator:
Me.TextBox1.InvokeRequired returns false!!!! It should be True because the calling and creating thread are different.
No, it shouldn't. You created a new form instance from that thread, so you are not moving between threads.
If you want to access the form in UI thread, pass a reference of the form to the class. As alternative you can in class define and raise an event, which the form can handle.
 
thank you John

Thank you so much John!
I passed a reference of the form to the class:

Public Sub run(ByRef formtest)

and I called it from the form as:
Private Sub runtest()
Dim classvarinst As New Classvar
classvarinst.run(Me)
End Sub

and it works.:tears_of_joy:
 
Why ByRef? Are you planning on assigning a new value to the parameter inside the method? If not then it should be ByVal.

Also, while passing the Form reference in will work, it is a bit of a poor man's solution. The "more correct" option would be for the object doing the work to raise an event that the form can handle and then update its own UI.
 
Back
Top