ProgressBar with Thread & Timer Slow

Hi.

Using as base the Example Project “UIThreadingWithTimer.xojo_binary_project” (Example Projects/Desktop/UpdatingUIFromThread), I’ve add my code for making some calculations.

If I run the code directly (so not in the Thread), it takes 2 minutes in making all calculations.
If I put exactly the same code inside the Thread (so refreshing the ProgressBar), it takes 45 minutes in finishing and making the same calculations as above.

Any idea of why it’s taking so much time for making exactly the same?.

I need to add into my program a ProgressBar for indicating the end user how is going the calculation, but it’s the first time I’m adding something like this and I’m loosing something as it should not increase so much the total calculation time.

I’m using Xojo 2019 Release 3.1

Don’t update the progressbar multiple times per seconds. Only update the progressbar when you really need to change it.

did you run multiple Threads by mistake?
use AddUserInterfaceUpdate only once a second or each 3 seconds.

u know if you make a class with set super to Thread you can drag & drop your class it into a window?

I’ve increase the timer to 10 seconds (10000 in the period) and the issue is exactly the same…

[quote=493318:@Markus Rauch]did you run multiple Threads by mistake?
use AddUserInterfaceUpdate only once a second or each 3 seconds.

u know if you make a class with set super to Thread you can drag & drop your class it into a window?[/quote]

I’ve tested both (1 & 3 sec) and is the same. No. I’m just using 1 Thread. I don’t know about the class…

Thanks

and the thread priority is set to default or highest?
how do you start the thread?
if you put a return in the run method for a test there is no delay?
have you put a system.debuglog(datetime.now.tostring) at the beginning and end of the run method?
what are you doing with this timer?

The Thread priority is set to default (5)
I start the tread using the timer… so like this:

if Thread_ICC.ThreadState=Thread.ThreadStates.NotRunning then Thread_ICC.Start end if
The run method has no return. Then the Thread finish his job, I’m continuing with other methods the calculation process and finally I’m saving all into a file. I’m controlling the thread has start and stop and the launch of the next methods using two timers.

I’ve not log the method… but as it’s hard to explain without the code, I’ve record a video showing the code (you can pause it on each screen for reading with detail) and showing the problem

Link for the YouTube video here:

Without the thread, you run the code once. With the thread, you run the code 100 times. So it takes 100 times as long.

You can’t just take the non-thread code, copy it into the thread, and then put a loop of 100 around it because you have a progress bar to update. Your code that does the work will have to be able to know that it has done 1%, 2%, 5%, 10%, etc of the work and then set the progress bar accordingly.

If your code starts, does work, then finishes, you will not be able to have a useful progress bar.

Video was very useful, by the way, for seeing the code :slight_smile:

[quote=493352:@Tim Streater]Without the thread, you run the code once. With the thread, you run the code 100 times. So it takes 100 times as long.

You can’t just take the non-thread code, copy it into the thread, and then put a loop of 100 around it because you have a progress bar to update. Your code that does the work will have to be able to know that it has done 1%, 2%, 5%, 10%, etc of the work and then set the progress bar accordingly.

If your code starts, does work, then finishes, you will not be able to have a useful progress bar.

Video was very useful, by the way, for seeing the code :)[/quote]
Thanks a lot for the explanation. Now I understand what was going on. I didn’t realise I was executing my code in a loop. I’m soo noob…

Thanks

We all have our moments of learning.

thats why i mention system.debuglog for seeing the program flow, its very useful and can remark later.

Did you just do this as an exercise, or do you have a real need for the app to be able to do other things while waiting for a rendering to finish? Otherwise a thread is possibly not of much use in your app, although always interesting to learn how to do it.

You could allow the thread to do everything, including saving the file, and you might then no longer need the timers. It would involve passing different pairs or dictionaries to the update event handler and a select-case in the event handler to handle the different work items you pass to it.

For some apps, where the progressbar is not really needed, I just show a window with a label saying something like “Work in progress”, and at the end I close the window.

Thanks all for all the tips. I need the progress bar (or your good idea about showing something Tim), as the calculation time now is 25 minutes, so I need to proof to the end user the code is still running or they will think the app has hang up.

I know this time sounds crazy, but I’m still improving the algorithms. In fact, one of the things I’m trying right now is splitting the process into Shells for using several CPUs for the process, but then I’m facing a different issue… I’ll post it in other post as it’s something absolutely different.

Thanks again to all of you for the help.

Splitting into helper processes can be a challenge, there are aspects to consider that aren’t always immediately obvious on the surface. I recently explored helper apps and wrote a small blog post about what I’d found, hopefully it helps you plan :slight_smile:

From what I recall, your overall algorithm seemed to be in 6 or 7 steps, yes? Do all these steps take about the same time? You can divide the 100 by 6 or 7 and increase the progress bar value after each one. On the other hand, if the first step takes 90% of the time and the others 1% each then it’s less useful.

You can also set the ProgressBar.Maximum to the number of steps and increment by one after each step :slight_smile:

But then, what’s the difference between a Helper and a Shell?.. witch will allow to create a better multithread application?.

Shell is a class within Xojo that you can use to control your Helpers. A Helper is another program we launch to perform the task. In my case, I launched the same executable with parameters to turn it into a Helper. The Helper would feed status updates to the main process through stdout, which the main process would catch with it’s Shell object.

Hope this helps :slight_smile: