Threads freeze during changes on UI

My application’s threads freeze until I move, resize the window, or I act on elements such as scrollbars.
Is there a way to avoid this problem?

Which platform/build type and what priority is the thread?

Plattform: Win 10 Pro
Priority : 5 (normal)
Build Type: Desktop

Test app is available here

Xojo threads are just time slices. It seems on Windows, resizing a window is a blocking action. There are other actions that block such as FolderItem related things. If you have something critical you could offload it to a helper app.

1 Like

In Xojo, all UI events are triggered (and handled) on the main thread. Since only one thread is running at a time in Xojo, this means that all other threads are suspended while the UI is being manipulated.

If you have background tasks that you want to continue running during UI changes, you’ll have to spin them off as Workers, or console applications that communicate with your main application. Or, if you are doing a lot of work in the main thread in response to UI changes, you may need to add some calls to YieldToNextThread to allow your other threads to run.

Looks like that keeping MouseDown on interactive places, as the Title Bar, resizable borders, menu items… are locking the UI in Xojo (at least under Windows)… And in Xojo that means locking everything.

1 Like

What you’re experiencing is something that several of us have been complaining about for around a decade now. Xojo does not support proper concurrency, it does EVERYTHING on the same thread, so when actions altering the UI occur, they stop it from doing other tasks.

This is for your own safety. Xojo once said they could easily adopt proper concurrency, but it would allow customers to blow their toes off.

I can tell after two months of using an alternative tool (which supports proper concurrency) my toes are still intact. My apps, now complete their tasks quicker and all without freezing the UI. The IDE of the other tool has been very helpful in learning how to do it.

If you want to just run a task without blocking the UI and don’t care about how fast it is, you can create a helper application to do it (again these are better done with other tools) and then you can use an Asynchronous shell to interact with the helper. If you do target the macOS, you should use NSTask declares for this, because Xojo’s shell class is needlessly inefficient, and doesn’t allow you to choose performance cores or efficiency cores.

Understand that for years, I wanted to fix these things (and several dozen others), but after multiple attempts, I was finally told that Xojo is as it should be and my help is not needed.

10 Likes

Hi Sascha, if i add a CMainThread.YieldToNext in your test project, in a new Resizing-Event of the Window, the thread seems to be executed. But then it stops, when i do not move the mouse, but keep the mouse button pressed.

Workaround
I put a timer in the window that invokes the command: app.doevents(50).
This activates the theads. With the timer.period setting and app.doevents(X) parameter I can balance the performance of the UI with the running threads.
If X value is too big, the UI becomes slow.
In any case threads become slower than normal but don’t freeze :cold_face:

doevents is strongly discouraged for Desktop apps. May search forum for it. Its only useful for Console Applications, where there is one thread, as i understand.

Using DoEvents() you may fire another cascade of events in a improper time causing unpredictable results.

Right, but at the moment I have no alternative.
My classes handle TCP links with protocols that have receive and transmit timeouts.
Without this change, I lose communication every time.

Sounds like you have something critical, which I’d mentioned an option for:

3 Likes

The idea is good but requires a lot of work to interface the app helper with the main application through TCP loopback.
Has anyone done something like this before?

That is bad

That is REALLY BAD.

The doevents can mess with the Socket events and cause nasty hidden bugs hard to fix.

1 Like

I never use events with threads

Eh? Which events do you never use with threads? All my comms with remote mail servers is done with sockets using the standard events that sockets provide. How else would one do it?

Fww I use app.doevent a lot and I never had any issues with it.
In fact in some occasions it is needed to not freeze things. But if you can avoid using it, you may do so.

Actually, you don’t need to use a network socket to accomplish this. If you write a console app to handle the time-sensitive protocol work, you vac communicate with it via pipes (STDIN/STDOUT) using the Shell class. That part is really fairly simple to get working, although you’ll then need to isolate the necessary code from your current app, encapsulate it into a console app, and work out a communication protocol between them. :wink: Not as simple.