Responsive GUI

Hello, im new to xojo
i would like to ask if there is a way to run heavy process/task while keeping the UI alive without using threading in xojo
thanks in advance

Worker f.e.

1 Like

or use Shell class to run a console app made in Xojo.

2 Likes

Thank you for your reply
should i use the Shell class to run the lengthy task?

thank you for your reply

Hi Jana:

As a Xojo beginner and not knowing about workers, shells and threads, I simply splattered app.doevents throughout my computationally intensive code. This achieved what you want to do. I thought I had failed, but then discovered that it was Microsoft Defender that was messing with me. After switching to a different anti-virus, Xojo code flew.

My plan is to move the computations to a thread, but that has low priority at present because the current Xojo code is good enough to process 500 data points a second while allowing for user interaction.

App.DoEvents is horrible advice for a Desktop application.

There simply aren’t enough experts left to explain why it’s a terrible idea, so you can either accept that it is or you can wonder why your app crashes in the future. I am not arguing with a brick wall today.

10 Likes

I second @Tim_Parnell in this. Don’t do that. DoEvents is a command meant only for console apps to facilitate a main event loop. Use of the command for anything else basically makes your apps do things that are not debuggable and by the time you realize that, it’s going to require huge amounts of refactoring to fix.

Use Threads, Workers and/or Console to accomplish this and you’ll be much happier on the long run.

@Xojo, how about deprecating DoEvents for desktop projects… or even better, make it a no-op!

8 Likes

No. Been using it (sparingly) for decades without issues, despite all the dire warnings.

2 Likes

There’s also @Kem_Tekinay’s Looper thing:

1 Like

Aaron Ballman (a previous staff member) has something to say about that attitude:
Why Is App.DoEvents Evil

3 Likes

It all depends on what the processing looks like. If a function needs to be continuously performed on a set of data, Looper is a good option.

But we really don’t know enough.

However, I will second the sentiment of “do NOT use DoEvents in anything other an a console app”. Doing so creates an event loop within your event loop, and saying, “but it works for me” is like saying, “I’ve been throwing lit matches onto my carpet and my house has never burned down.”

Just. Don’t. Please.

6 Likes

Would:

thread.YieldToNext

do what these folk want?

No, all that does is force the app to yield time to the next Thread. If there are no Threads, I don’t think it does anything.

And it shouldn’t really be needed. If you want your Thread to get more processing time, change its Priority. Otherwise, the framework will yield as needed on loops.

Further, forcing a yield can actually slow down processing since context switches are expensive.

I’m surprised nobody’s mentioned Timers yet.

Rather than doing a loop, you can code each iteration of your work into a Timer.Action event and update properties within your window or class to save state between events. It’s not very efficient, but it’s easy to wrap your head around as a beginner.

Ultimately, threads are the better approach, and when you see how much faster they run versus timers you’ll want to make the switch. But if you just want to get it done quickly, you can do it in a timer and keep your UI responsive.

FYI, that’s essentially what my Looper class does.

Thank you all for your responses. Your help is much appreciated.

Thank you @Kem_Tekinay for your response .
I have a lengthy mathematical operation running (svd f.e.). I don’t want the UI to go non-responsive while the operation is running, and I want to show a progress bar for the user.

Apologies for questioning your design choices, but I’m curious as to why you ruled out threading. It’s really very simple: your main window starts the thread, then a timer in the main window checks the thread periodically to monitor its progress while the GUI stays responsive and user can do other stuff. In the timer’s Action event, you can, for example, check a “progress” property of your thread subclass and set the main window’s ProgressBar accordingly. No need to even use Thread.UserInterfaceUpdate if you don’t want to.

1 Like

Thank you a lot, @Julia_Truchsess, for your feedback. Actually,i never used a thread before, so that’s why I was trying to avoid it. But now that it looks like the best practice, I will read more about it and try to implement it in Xojo.
Thank you again.

2 Likes