views:

195

answers:

3

Sup Guys,

I Have a Function on my frmMain Class wich will update my control to something else after an invoke. When i type "?Label1.Text" on the Immediate Window, the text property IS updated, but when i go check the Form, nothing happened. The code is just like this

Public Sub UpdateUI()
    If (Me.InvokeRequired = True) Then
        Invoke(New MethodInvoker(AddressOf UpdateUI))
    End If
    Label1.Text = "ITS NOT WORKING =\"
End Sub

On my bgWorker Class:

Private threadUpd As New Threading.Thread(AddressOf Updater)
Private _active as Boolean
Public Sub New()
    _active = True
    threadLimpar.IsBackground = True
    threadLimpar.Start()
End Sub

Public Sub Updater()
    Do
        If (_active = False) Then
            Try
                Thread.Sleep(Timeout.Infinite)
            Catch ex As ThreadInterruptedException
            End Try
        Else
            if(condition...) then
              frmMain.UpdateUI
        End if
    Loop
End Sub
+2  A: 

You probably should terminate the function if InvokeRequired returns true, but you're setting the label text anyway. Here's what you might do:

Public Sub UpdateUI()
    If (Me.InvokeRequired = True) Then
        Invoke(New MethodInvoker(AddressOf UpdateUI))
    Else
        Label1.Text = "ITS NOT WORKING =\"
    End If
End Sub
Aviad P.
Wish I could type faster, lol :D
Paolo
I'm tempted to downvote just because you're performing equality comparisons between a boolean and a constant, but the OP's question did it so I'll +1 anyway. Use boolean operators.
Adam Robinson
Well I think I'm a dumbass cause this deffinitly does NOT work, altho, as i said, I can see it was updated if i check the Immediate Window, but the form itself got no update.Any other hints
Alex
+1  A: 

I think you want the following:

Public Sub UpdateUI()
    If (Me.InvokeRequired) Then
        BeginInvoke(New MethodInvoker(AddressOf UpdateUI))
    Else
        Label1.Text = "ITS NOT WORKING =\"
    End If
End Sub
Paolo
Still does not work, the label wasnt updated on the form, altho i can see it was "updated" thru the immediate window
Alex
Going on the code in your question, this solution should update the label text.
Adam Robinson
Well I think I'm a dumbass cause this deffinitly does NOT work, altho, as i said, I can see it was updated if i check the Immediate Window, but the form itself got no update. Any other hints?
Alex
What else is going on on the UI thread after kicking off this background thread?
Paolo
+3  A: 

It is a classic trap in VB.NET, everyone falls into it at least once when they start using threads:

frmMain.UpdateUI

Now we can't see what exactly "frmMain" means. But the fact that you posted this question suggests that frmMain is the name of your main form class. Not the name of a field in your class that stores a reference to the main form.

That doesn't work. The variable that the VB.NET compiler generates to allow you to reference as class as though it is a variable has <ThreadStatic> semantics. In other words, every thread will create its own instance of a the form. You can sorta see it when you write it like this:

frmMain.UpdateUI
frmMain.Show

But you'll see a "ghost" of the window, it is otherwise dead as a doornail since the thread it was created on is not pumping a message loop.

You'll need a real reference to the form. That could be "Me" if Updater is a method of the form class. If it isn't, Application.OpenForms could provide it. Best thing to do is the give the class that contains Updater a reference to the form through its constructor.

Hans Passant
I was almost sure it was something like this but can you give me an example how im referencing my already-opened form?
Alex
Works Perfectly!
Alex
+1. Never knew that the VB.net "pseudoinstance" was `ThreadStatic`. That would make complete sense!
Adam Robinson
Thanks for the +1.
Hans Passant
+1. Well well, there's an odd twist.
Paolo