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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With