If I understood well, the app runs in the main thread, if some methods take long, the apple OS shows a spinning color wheel. I tried to show a window with a simple text like “Wait, processing…” and a counter.
But this do not work because when I open the window which it creates a thread I’m opening the window in the main thread, no? And the window is not updated until the long process is over.
Probably I should open a new thread and this opens the WaitwWindow but I could not find an example or a way to implement this.
This is how I implemented it, the thread is started in the window open
Sub Open() Handles Open
But this does not work, the window open as blank window and keeps this state until the procedures that take long have finished.
It won’t work, especially if you’re not sleeping the thread during your code within that thread. When you call myThread.Start in Open, the Open event won’t complete until either the Thread sleeps or completes its work. That’s why I suggested using a Timer with its Mode set to Off and Interval set to 50. Then, at the very end of your Open event, set the Timer’s Mode to Single.
Threads are managed by the built-in Thread Scheduler. Its task is to allocate the CPU’s processing cycles among all of the application’s threads. Note that because Threads are cooperative, they all share the CPU cycles of a single CPU core. Threads cannot access other CPU cores. The Priority property determines how many or how few processing cycles the Thread gets, relative to the main thread (which always has a priority of 5) and any other Threads that you have created. Use a higher value for Priority to give a thread more CPU cycles and a lower value to give it less CPU cycles.
Threads run in the background, but are temporarily blocked by certain user actions:
While the mouse button is held down,
While a window is being dragged,
While a menu in the menu bar is pulled down,
While the mouse button is pressed on a control in a window (not true of Windows)
When the Thread Scheduler decides to stop execution of the current thread and allow another thread to run, it is called a context switch. The amount of time a thread runs is called the time slice for the thread.
Threads can yield time to other threads and other applications each time they execute a looping construct such as For, While, and Do. However, a thread does not necessarily yield time at every loop boundary even though it has an opportunity to do so. A thread actually yields to another thread when the Thread Scheduler decides that its timeslice has expired. Context switches are expensive, so the Thread Scheduler always tries to avoid them.
I would have expected that calling start() merely queues that thread for execution, and that the Open then continues to completion. At which point the scheduler looks for threads or events requiring CPU time and the newly started thread gets some CPU time according to the various priorities.
That would likely cause unexpected behaviors as compared to the way other operations in the Xojo language happen. I, personally, expect something to start when I tell it to start, rather than at some random time later.
I don’t see anything in the doc page you referenced to say one way or the other. My expectation is based on prior experience of writing thread/task based systems. I would find it strange if the Open were blocked in the way you describe.
Testing in the latest version of Xojo, however, I don’t see the lockup that used to be indicative of using the Thread class in this manner. Likely due to the addition of UserInterfaceUpdate incorporating a Timer internally to check for messages that need to be sent. So something else is probably going on here.
Yes I know that and I use them in my threads. If a thread gets priority immediately, then the implication is that one might do worse than to put a yield in as the first statement of any CPU-bound thread.
The log in my app shows 5 threads all starting at once (within the same second). These are all started in a loop in a timer event, but my threads all do lots of I/O and not much processing, so I can’t tell from that whether the timer event is held up until a thread happens to wait for I/O.
My assumption has always been, however, that starting a thread just queues it, rather than switching to it immediately. I’ve not seen anything to contradict that.