Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Synchronize is being locked by ShowModal?

Tags:

delphi

I created a generic thread class that controls a progress form which is injected in the constructor of the thread and set as _progressForm. At the Execute method, the thread initializes the form and shows it using the function ShowModal() as shown below:

procedure TProgressThread.Execute;
begin
  ...
  ShowForm;
end;

procedure TProgressThread.ShowForm;
begin
  if Assigned(_progressForm) then
  begin
    Synchronize(
      procedure
      begin
        _progressForm.ShowModal();
      end);
  end;
end;

What I can't understand is why my thread is locked at Synchronize? It doesn't return until the progress form is closed. Shouldn't ShowModal only lock the main thread?

like image 766
noen Avatar asked Dec 13 '22 20:12

noen


1 Answers

TThread.Synchronize() is synchronous. It blocks the calling thread until the synced code returns from the main thread.

ShowModal() is also synchronous. It blocks the calling thread until the Form is closed.

So, when Synchronize() calls ShowModal() in the main thread, Synchronize() will not return to the worker thread until the Form is closed.

If you don't want to block the worker thread, either use TThread.Queue() instead of TThread.Synchronize(), or use TForm.Show() instead of TForm.ShowModal().

Display of progress should not block the worker thread from doing its work. You should have the thread asynchronously post progress updates to the main thread, and let the main thread decide how to display the status while the thread continues with its work. The worker thread should have no knowledge of the UI at all.

like image 72
Remy Lebeau Avatar answered Dec 27 '22 12:12

Remy Lebeau