Real Software Forums
http://forums.realsoftware.com/

Delegate and threads
http://forums.realsoftware.com/viewtopic.php?f=21&t=47917
Page 1 of 1

Author:  bineo [ Sun May 19, 2013 8:45 am ]
Post subject:  Delegate and threads

Hello everybody

I just played around with delegates and threads. I have a simple method which counts up an integer and writes it to a textfield. If I run this the classic way (in the run event of the thread) all runs nice, the GUI is responding and the counter is displayed. But if I make this with a delegate I have to add a app.doEvents line to the loop otherwise the app doesn’t respond anymore.

Is this normal? Or have I done something wrong?

Thanks
Marco

Author:  timhare [ Sun May 19, 2013 3:22 pm ]
Post subject:  Re: Delegate and threads

You've most likely done something wrong, but you'll have to provide a lot more detail for anyone to figure out what you did wrong.

Author:  taylor-design [ Sun May 19, 2013 4:51 pm ]
Post subject:  Re: Delegate and threads

timhare wrote:
You've most likely done something wrong, but you'll have to provide a lot more detail for anyone to figure out what you did wrong.


Agreed.

Beyond that, nothing in a thread's call chain should touch the GUI. It's explicitly forbidden on Cocoa, and will be in coming versions of Xojo on all platforms.

Author:  bineo [ Mon May 20, 2013 3:30 am ]
Post subject:  Re: Delegate and threads

OK, I've uploaded the Project http://www.unimatrix0.ch/Delegate.zip

My intention was to have a thread class to which I can pass a method instead of making a subclass everytime. If I remember it right I could do this in VB.net

Author:  charonn0 [ Mon May 20, 2013 12:50 pm ]
Post subject:  Re: Delegate and threads

You've overridden the Thread.Run method and are running the delegate from within that method. In order for the thread class to operate cooperatively, threaded code must be called from within the Run event.

The built-in version of the Thread.Run method is what causes the Thread.Run event to be executed. Since you've overridden this method you need to make sure to call it from within the override method. You can call an overridden method by using the Super keyword.

Add a property to you custom Thread class (e.g. MethToRun As ThreadMethod). Then re-write your overridden Run method like this:

Sub Run(Meth as ThreadMethod)
Me.MethToRun = Meth
Super.Run() 'Call the overridden Thread.Run method
End Sub


This will trigger the Thread's Run event, where you can Invoke the delegate in a non-blocking manner:

Event Sub Run()
Me.MethToRun.Invoke()
End Sub


Though, as has been stated, Threads + GUI tampering = :(

Author:  bineo [ Tue May 21, 2013 1:19 pm ]
Post subject:  Re: Delegate and threads

First, thank you for the excellent explanation.

Because of your note that is prohibited to manipulate the GUI from within a thread I tried applying what they showed in the example of the thread class in the LR. I put the counter in the module and made a timer which writes it to the textfield. But surprisingly the GUI is still affected for example when you move over the buttons the cursor.

Is that still the wrong way?

Author:  taylor-design [ Tue May 21, 2013 2:02 pm ]
Post subject:  Re: Delegate and threads

bineo wrote:
Because of your note that is prohibited to manipulate the GUI from within a thread I tried applying what they showed in the example of the thread class in the LR. I put the counter in the module and made a timer which writes it to the textfield. But surprisingly the GUI is still affected for example when you move over the buttons the cursor.

Is that still the wrong way?


My guess is that you're never actually running on a thread. As was pointed out above, subclassing Thread and adding a method with the same name as the Run event means your code is not actually executing in the thread, i.e. from the Run event.

Quote:
My intention was to have a thread class to which I can pass a method instead of making a subclass everytime. If I remember it right I could do this in VB.net


You don't need to subclass Thread to accomplish this. You just need to use AddHandler:
http://docs.realsoftware.com/index.php/AddHandler

Here's a snippet of code from a Window in one of my projects. Task is a Window property of type Thread, and ImportRun is a method of said Window with the following signature:
Protected Sub ImportRun(objCaller As Thread)

Self.Task = New Thread 'Note that I'm using the generic Thread class.
AddHandler Task.Run, AddressOf ImportRun 'ImportRun will be called when the thread starts.


Notes:
* The handler method must have the correct parameters for whatever event is being handled.
* Inside the handler method, Self refers to the instance which owns the method (if any). The caller, in this case a Thread, is passed as a parameter. In the example above, my handler can access any properties or methods of the Window, though it still can't do something that updates the GUI.

I downloaded and modified your sample project to use AddHandler and a GUI update timer.
http://webcustomcontrols.com/freeware/addhandler.zip

Author:  bineo [ Wed May 22, 2013 2:06 pm ]
Post subject:  Re: Delegate and threads

Well, looks like going through the whole RB curriculum would be a good idea. ;-)

It’s actually pretty simple. Except the parameter that is needed doesn’t look logical to me by now. What I discovered is that even running in a thread it seems to slow down the gui. If you run the method and hover over the buttons the disappear while adding the blue background. Is that because the method runs to fast?

Thanks again for the explanations

Author:  timhare [ Wed May 22, 2013 2:25 pm ]
Post subject:  Re: Delegate and threads

Threading is not an automatic cure-all. You need to tune for throughput vs. responsiveness. Try lowering the priority of the thread. Or add periodic app.YieldToNextThread calls.

Page 1 of 1 All times are UTC - 5 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/