How to make the main thread (caller) wait for a child thread to complete execution?


Using: Delphi 10 Seattle, Win32 VCL forms application

I'm developing an updater application that checks for updates to one or more installed software applications, and when updates are found will download the updates in sequence. After each update is downloaded, it will install the update before proceeding to download the next update. The downloading bit is implemented as a thread class (descendant of TThread) and its constructor is as follows:

constructor TWebFileDownloaderThread.Create(CreateSuspended: Boolean; const AWebFileURL, ALocalFilePath: String;
  ACallBackProc: TProgressCallback; AProxySetting: TProxySetting);
  inherited Create(CreateSuspended);

  FWorkResult := False;

  FWebFileURL := AWebFileURL;
  FProxySetting := AProxySetting;
  FLocalFilePath := ALocalFilePath;

  FUpdateCallbackProc := ACallBackProc;

The main thread creates and starts the downloader thread as follows:

procedure TfmMain.DownloadUpdateFromWeb(const AInstallerFileURL: String);
  internet_file_download_thread: TWebFileDownloaderThread;
  internet_file_download_thread := TWebFileDownloaderThread.Create(True, AInstallerFileURL, FUpdateDownloadDir,
    UpdateProgressCallback, FProxySetting);

  internet_file_download_thread.OnTerminate := WebFileDownloaderThread_TerminatedMethod;
  internet_file_download_thread.FreeOnTerminate := True;

My specific question is: How to make the main (calling) UI thread wait until a downloader thread completes, before creating a new downloader thread to start the next download?

I believe that there is some form of queuing required, but not sure how to implement it. Your tips and advice are much appreciated.

If I understood it correctly, you have a list of URLs to download and install (obtained by previously performing a check for updates). You want to download updates from these URLs and install them one by one: download update 1, install update 1, download update 2, install update 2, etc.

Here's a possible design:

In your WebFileDownloaderThread_TerminatedMethod, start installing the just downloaded update (to keep the main thread responsive, do this in a separate thread).

In the OnTerminate handler of the installer thread, remove the just completed URL (or mark it as processed) and start downloading the next one, by calling DownloadUpdateFromWeb again, unless the list is already empty (or contains no more unprocessed items).

(BTW, the method DownloadUpdateFromWeb would better be named something like BeginDownloadUpdateFromWeb, to indicate its asynchronous nature.)