Threading, class and GUI

LeonR

Well-known member
Joined
Nov 2, 2006
Messages
139
Location
UK
Programming Experience
10+
Hi guys, I know this is probably a common one, its also quite tricky to know how to get around it (I find anyway).

I have a seperate thread, within that thread I have defined an object (of my own class).

Obj.UpdateMyForm is called, but how do I get the code from my class to update the form?

Normally, I would use a sub routine with the following


VB.NET:
Sub Update()
  if me.InvokeRequired = true then
         me.invoke(new methodinvoker(addressof update))
else
    label1.text ="test"
end if

I found this code online a while back, and it seems to work if I call the sub routine directly from another thread, however, calling it from one of my class sub routines doesn't seem to work.

Has anybody any suggestions? If i'm honest, this invoke code confuses me a little, i'm not 100% on whats actually going on behind the scenes :confused:
 
It's got nothing to do with what thread you call it from. It's purely and simply whether 'Me' has an InvokeRequired property and an Invoke method. Basically, it must a control, which includes a form, to have those members. If you want to use those members outside of a control then you must have access to a control to use its members. It doesn't matter what control it is, as long as it was created on the appropriate thread.

You don;t even have to have that code in your class though. Your class can call a method of the form and then that code can be in the form, so you can then use 'Me' again.

For more info, check this out:

Accessing Controls from Worker Threads

For an example of using the ISynchronizeInvoke interface outside of a form or control, check out the project attached to post #82:

Asynchronous TcpListener & TcpClient
 
Hi, thanks for your reply!

I had a go at implementing the first link... so basically this is what I have..


my class (object defined in another thread)

VB.NET:
  Form1.UpdateLabel("test")

^^ keeping it simple :D


Now in my form, I have..

VB.NET:
Public Delegate Sub UpdateLabelInvoker(ByVal LabelText As String)


    Public Sub UpdateLabel(ByVal LabelText As String)


        If Me.Label1.InvokeRequired Then


            Me.Label1.Invoke(New UpdateLabelInvoker(AddressOf UpdateLabel), Text)

        Else

            Me.Label1.Text = LabelText 


        End If


    End Sub


Running this code does nothing at all to the GUI. I'm doing something really wrong here?

This kind of concept usually works ok when i simply call it from another thread, but for some reason, my class 'within' another thread is not complying :confused:

Thanks!
 
VB.NET:
Form1.UpdateLabel("test")
Running this code does nothing at all to the GUI. I'm doing something really wrong here?
If "Form1" here refers the default form instance you must be aware that default form instances are specific to each thread, so if you call this from a secondary thread then you're essentially interacting with a new form instance.
 
Hmm, that would make sense I guess!

If I put 'beep' next to label1= then I get the beep noise, which indicates the thread is calling the routine ok, just not running in the right instance?

How do I actually call it the correct way? The thing that confuses me is that this would normally work if I was simply calling it straight from a 2nd thread, but because im implementing this code through an object of a class that is created 'in' the 2nd thread, its not working for some reason?

Really stuck on this one, it should be easy though, I must be really missing something obvious! :(

What should I use instead of 'form1' ?


My structure is kind of like this..


[form load code]

Start Thread2

[end of form code]




[thread 2]

dim Obj as new myupdateclass
Obj.Updateform

[end thread 2]




[myupdateclass ]

sub updateForm

form1.updatelabel("hello")

end sub

[end class]




Thanks for your reply :)
 
Last edited:
I think that you should forget the ISynchronizeInvoke interface, i.e. the InvokeRequired and Invoke members, and use the SynchronizationContext class. It will be simpler. Go back to the second link in post #2 but get the project attached to the first post instead. It uses the SynchronizationContext class.
 
Ok thanks for the help, I will have to seriously sit down and read up on this stuff as its holding me back with threaded apps.

For the moment I have got around the problem using a backgroundworker which implements the progress event, so I can then use shared variables (in another class) to check from the UI code.
It's not great, but it should suffice for what i'm trying to do, which is basically update a few labels and a picture box!

Thanks,
Leon
 
Back
Top