It doesn’t matter how long the code is running, the Window does not hide. If I call an AppleScript between Hide/Show everything works as expected. When I remove the Show command at the end the Window will hide but only when the Method ends.
In modern computer systems, the UI is updated when the event stack has completed. Hide and Show aren’t being drawn until the exact same time: when your long-running code has finished.
You need to put long running code in a Thread so that it doesn’t lock up the UI drawing.
DoEvents should trigger an analyzer warning. Something like “This method may cause your app to misbehave.”
People use DoEvents out of laziness, but I think just telling people not to, or even why not to, is not really an effective solution. We need easier tools to solve these kinds of problems.
If Xojo has closures and promises, the language would catch up to the last ten years of common practices. You could then do something like
Though I admit, the real syntax would have to be something… different. Regardless, giving us some way to do the desired task without teaching the user about threads, addhandler, interface update, etc. would go a long way to helping users develop better apps.
simple said a method call will interupt the main event loop in xojo.
that is why your call with doevents solve your problem somehow.
instead of
hide do show (all in one)
try
hide
do
show
for longer methods over few seconds you need a thread.
xojo could change this behavior but they will not do.
Thanks to all for helping. I realized that the Timer does not speed up things as I thougt. So I think threading will be better. Is it possible to dynamically create multiple threads, so if thread 1 has not finished its work, then create a new one? The Desktop Example shows 4 threads tied to a window. My threads should work without a window being called from a Method App.Action().
Thanks for the hint. It seems not to work when the Thread calls a shell command. That seem to block the whole App until the command has finished. In this example I play a longer sound. In my real code, I call several shell commands depending on the results.
Var sh As New Shell
sh.Execute("/usr/bin/afplay /System/Library/Sounds/Submarine.aiff")
// Process sh.Result …
Not every action is thread friendly in Xojo. FolderItem actions you’ll find behave similarly. I whipped up a test project and can confirm what you’ve found about afplay + synchronous shell + thread.
You may need to refactor your design using asynchronous shells instead to free up the UI.
Thanks again. Didn’t imagine that it will get so complicated so fast.
How can I store the returned result so that the calling thread which is waiting for it gets the right one? Or do I have to split my code with multiple Shell commands into a lot of Completed() methods? But how do I transfer the values from one to next?
Is it right that async Shells can’t be created with code, but only by an item in the left sidebar? This seems not to work:
Var sh As New Shell
sh.ExecuteMode = Shell.ExecuteModes.Asynchronous
sh.Execute("mycommand")
In the DataAvailable event move the data to a property with ReadAll. The design of your classes/subclasses will determine the plan for this, so we’ll keep moving for now.
This would be best, really. We can design a class/subclass architecture that keeps things clean in your sidebar while still doing what we want.
I might recommend a design where you have a class that acts as the “controller”. You could optionally use Thread as a superclass for this, but if it’s mostly just waiting for shells I don’t see it as necessary. The controller class would retain the results and move them from one shell command to the next.
You can create them in code, but you still need to retain the reference while it runs. You can store it in a property of a window, class, module, or whatever. Yes it still shows up in the navigator, but it would be a property. If you really really don’t need to subclass Shell for this it can be done, but that doesn’t always mean that you should.
late thanks for your investments and the example. I haven’t transferred it to my project yet. Before I start learning, one question: Would a Worker be easier to implement, or will non-async shell commands in a Worker also block the whole App?
Just be aware (in case you aren’t) that when you run a project in the IDE, threading is used to simulate the function of the Worker. The true performance can only be gauged in a built app.
Thanks for your additional hints. After some investigations, I came to the conclusion that chained shell calls are impractical in my case. I use a lot of shell command likes conditional mkdir with -m parameter, sips and screencapture. It seems it’s better to transfer some parts my App into a shell script so that I only have one shell.execute in my Xojo Project.
I also could transfer all shell command to native Xojo code. Creating folders with permissions shouldn’t be hard, cropping/resizing images seems also to be possible, but what about “screencapture”? Is it possible without using MBS?