mr-highball: similar named methods don't mean they are cooperative multitasking, like some other languages have.
On Windows there are the various waitformultiple variants, which are even more powerful.
In such case, all threads have an tevent you can wait on, like await, but you can select the threads you want to wait on (in case there are many).
Moreover, you can give a timeout and check for that and run the message pump in the meanwhile.
E.g. in one of my apps (Delphi, but Lazarus is totally similar) I
- fire up a couple of threads that do the initialization, and hold a list of their tevents.
- Then I show splashscreen.
- I then enter a loop like this:
while not waitformultipleobjects(list,450) and (iterations>0) do // 500ms
begin
application.processmessages; // process events
checkthreadlistfornewmsgsandshowonsscreen();
dosedsleep(50); // runs application.processmessages in a loop with a sleep till 50 ms are done to process
dec(iterations);
end;
This shows the splashscreen for iterations*(450+50) ms while being somewhat responsive (resizing, hide/display) and showing messages from the threads that they log to a threadlist.
Afaik this is old, and there are also variants that wait on (Tevent-) handles AND windows messages. Implementing this would make the response to windows messages a bit less sluggish, but I haven't bothered because the hardware that had the real long startup times is EOL.