[Lazarus] TThread.WaitFor blocks the main event loop under Linux

Michael Van Canneyt michael at freepascal.org
Fri Oct 8 16:15:58 CEST 2010



On Fri, 8 Oct 2010, Graeme Geldenhuys wrote:

> Hi,
>
> [Just as well the Lazarus IDE didn't get the thread update mentioned a
> few days ago... where a thread was doing work, and the main thread was
> waiting for that thread to finish... it wouldn't have worked under
> Linux it seems.]
>
>
> I just stumbled across this issue in fpGUI, and I see MSEgui and
> LCL-GTK2 has the
> exact same problem. See attached project. I haven't tried LCL-QT, but I presume
> that same issue will persist.
>
> A simple program (just for illustrative purposes), where a thread
> updates the progress bar (the thread could be doing any long running process).
> Click the button, it creates a thread and
> starts it off. If then waits for the thread to finish, then displays
> that it has finished in the GUI, and free's the thread manually.
>
> If you use the MyThread.WaitFor to wait for the thread to finish, then
> the application is instantly frozen (even the thread), nothing gets
> updated and you have to kill the process.

This is normal, since WaitFor() is a blocking call.

You should never use WaitFor() in a GUI app, instead, you should set a
callback on the thread Terminate, and run the message queue while you're
waiting. It's not different from showing a modal form with ShowModal().

Procedure MyForm.OnThreadDone(Sender : TObject);

begin
   FThreadDone:=true;
end;


Procedure MyForm.DoSomethingInThread;

begin
   T:=TMythread.Create(True);
   T.OnTerminate:=OnThreadDone;
   DoSomethingElse;
   While not FThreadDone do
     begin
     CheckSynchronize(10); // normally called in ProcessMessages.
     Application.ProcessMessages;
     end;
   // Now thread is finished.
end;

We could alleviate this by allowing to hook into WaitForThreadTerminate and
with this provide 'run message queue' callbacks.

Michael.




More information about the Lazarus mailing list