Progress Bar updation

I have a method that has an execution time of about 2 to 3 minutes.
I have to wait for the method to complete before going to the next method.
But in the meantime I would like to have a progress bar indicating the progress.
the ProgressBar.Refresh does not seem to work.
I have read that a thread needs to be used, but it is making my code complicated.
Is there any way of getting it done without the thread ?

one option is to set the mouse to hourglass and not touch the app in the meantime.

inside of a method the main event loop is interrupted / discontinued until this method end, then it continued. without this main event loop the app have no ui update and windows os let the app looks frozen / hang.

Unless you show your code everything you’ll get is only guess work.

But that indicates that you are doing something wrong.


without main event loop windows os said it not response and freeze.
Ashampoo_Snap_Samstag, 24. Juli 2021_9h19m37s_001_Untitled (Keine R�ckmeldung)

you can only bypass this behavior with a thread or doevents.
for understanding:

maybe you can split your 2 min. method in smaller pieces and run them one by one consecutive.
as example a timer event process one item of a list of tasks.

and to avoid app.doevent ( which is considered bad practice) you could also use a timer to run the refresh action.

Using a thread is not really that complicated and will do what you want to achieve.
Any other method is just a workaround which might influence the flawless function of your app – like the proposed DoEvents.
And you are not doing something wrong with ProgressBar.Refresh. Only that the OS’ have changed their Refresh behaviour – on macOS it is equivalent to Invalidate today, and that means that when your code cycles in a tight loop, the OS will update the GUI after the code finishes.
Use a thread.

Web is entirely threaded, and threads have complete access to the UI.

Desktop threads cannot touch the UI. So in order to address a control, one has to use a timer, which fires in the main thread.

if you stop the main event loop (with a longer method) there is no timer action event at windows os.
at least when the timer is inside the window.

it would be good practice if xojo handle all methods parallel.
its awful to put every method into a thread just because this condition.

Oh no…

No you don’t put every method in a thread. You only thread the stuff you expect to take longer than 2 seconds, or does lots of little things very frequently.


i have many methods that can run longer than a few seconds.
as example calculations or database related stuff.

Oh no…

why do you have this objections? it would be a improvement.
as example the timer event would tick parallel to a method which is for longer in execute state.

not direct but from 2019r2
via AddUserInterfaceUpdate and UserInterfaceUpdate it can

Because quite frankly, it doesn’t make sense. If you truly wanted every method to run parallel, you basically couldn’t code. Imagine this block of code:

Var Result As String = SomeProcess()

DoSomethingElse(Result) would be called even before SomeProcess() finishes. It just doesn’t make sense. This is why some languages have async and await keywords so you can make a method asynchronous and wait for its execution respectively.

Interpreting what you said a little differently, we’d still have massive problems if one iteration of the event loop did not wait for the previous one to complete. You can’t just make code run parallel and hope for the best. That’s what threads are for, so you can organize your intentions in a way that makes sense.

Technically no. The thread stores the dictionary on its instance and uses a timer to fire the UserInterfaceUpdate event on the main thread. The thread isn’t touching the interface at all.

I gave a talk about threading in Xojo a few years back. Imagine the event loop looks something like this:

Var Quit As Boolean = False
While Not Quit
  Catch Err As RuntimeException
    Quit = True
  End Try

This is all super-simplified made-up code of course, but the idea stands. While doing your work, you’re stuck in the CheckUserInput() phase of that block. You can’t reach the UpdateUI() phase until all your work is complete. If you want your app to remain responsive, you need to use a thread so the event loop can execute it in small bits, sharing time with the main thread and any other threads.


sorry for misunderstanding, i did not explained well.
i spoke about that the action click event method does not stop everything because this method is still executed.
parallel in context of not stopping the main event loop.

what i want is somehow the possibility that a action click event
is a thread and the method itself the run part.

I know, you want threading work for free. It’s not going to happen.


I do not know why there should be a restriction on updation of progress bar during a loop. Starting to use a thread even when I want to wait for the method to finish before proceeding further, just for this purpose is just too much work. I think the Refresh method should be made to work again.

1 Like

Unfortunately, that’s probably not going to happen. If you want to show progress of a long task – or even just run a log task without locking up the main thread (where your UI lives) completely – you need multithreading. Refresh had its own issues, DoEvents outside of a console application can also have undesirable side effects. @Thom_McGrath is not steering you wrong, and I think you’d be able to implement a thread a lot easier than you realize.

I have a thread which starts once an hour to do things like rotate log files and other housekeeping matters. All the work I do sending and receiving data to/from external hosts on the Internet is done with threads.

Doing this without threads would be very hard and make for a poor application.

I don’t think there is a restriction. But your application will be unresponsive during the time the method runs (well, it probably is anyway).

i agree
instead of “evil” DoEvents just a method which ms os trigger i am alive.

Thank you.