natli
natli

Reputation: 3822

Cannot update control from Class Function that works in a thread

Updating the TextBox from a Thread that calls a function within a Class does not work. I'm trying to get this to work in a DLL (but I tried without as well). The DLL is accepting an Object as an argument, like so;

Sub New(ByVal theObject As Object)

This allows me to send an object such as this one:

Public Class anObject
    Public Sub doSomething()
        Form1.TextBox1.Text = "test"
    End Sub
End Class

So I will be calling the DLL like this:

Dim theObject As New anObject
Dim theDLL As New SO_TBFromDLL.UpdateTB(theObject)

After which the DLL will start a Thread, that then calls "doSomething"

Public Class UpdateTB
    Dim theObjectSet As Object

    Sub New(ByVal theObject As Object)
        theObjectSet = theObject

        'Try to update TB from Thread within current class
        Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf bghandler)
        ctThread.Start()
    End Sub

    'Try to update TB from Thread within current class
    Sub bghandler()
        theObjectSet.doSomething()
    End Sub
End Class

But this isn't working. I also tried it using a delegate (code below).

I have been trying two other variations in addition to those two;

Try 3 from Thread that's not in Class/DLL. This works just fine.

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf receiverFunction)
    ctThread.Start()
End Sub

With receiverFunction being:

'Receiver for Thread that's not in DLL (Button 3)
Private Sub receiverFunction()
    generaldelegatesN("tb1", "test")
End Sub

Try 4 from Thread that's not in DLL, but use the Function inside of the Class. This does not work either.

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    Dim theObject As New anObjectWithDelegate
    Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf theObject.doSomething)
    ctThread.Start()
End Sub

With anObjectWithDelegate being:

'Unfortunately, with a delegate it still doesn't work (Button2 & Button4)
Public Class anObjectWithDelegate
    Public Sub doSomething()
        Form1.generaldelegatesN("tb1", "test")
    End Sub
End Class

Why does Try 3 work, but Try 4 doesn't? It's doSomething() function is practically identical to receiverFunction With the exception of the added Form1.

Delegation code: (In case it matters)

'The Delegate functions
Delegate Sub generaldelegates(ByVal param1 As String, ByVal param2 As String)
Public generaldelegatesM As generaldelegates
Public Sub generaldelegatesN(ByVal param1 As String, ByVal param2 As String)
    'Updates control on main thread:
    If Me.InvokeRequired Then
        generaldelegatesM = New generaldelegates(AddressOf generaldelegatesN)
        Me.BeginInvoke(generaldelegatesM, New Object() {param1, param2})
    Else
        Select Case param1
            Case "tb1"
                TextBox1.Text = param2
        End Select
    End If
End Sub

Upvotes: 0

Views: 578

Answers (1)

J...
J...

Reputation: 31463

You're trying to hard code a reference to an external object inside a separate class that has no idea about what objects are instantiated elsewhere. Your class object would need to have the textbox reference passed to it like this :

Public Class Form1

    Private myObject = New anObject

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        myObject.doSomething(TextBox1, "test")
    End Sub

End Class

Public Class anObject
    Public Sub doSomething(ByRef obj As Object, ByVal message as String)
        Dim objType = obj.GetType()

        If objType Is GetType(TextBox) Then obj.Text = message

    End Sub
End Class

Upvotes: 1

Related Questions