RAD Studio |  |

Waiting for Threads
See Also
Collapse All

The following are procedures that can be used to wait for threads.

- Wait for a thread to finish executing.
- Wait for a task to complete.
- Check if another thread is waiting for your thread to terminate.

To wait for a thread to finish executing

1. Use the WaitFor method of the other thread.
2. Code your logic. For example, the following code waits for another thread to fill a thread list object before accessing the objects in the list:

Copy Code

    if ListFillingThread.WaitFor then
    begin
      with ThreadList1.LockList do
      begin
                    for I := 0 to Count - 1 do
          ProcessItem(Items[I];
      end;
      ThreadList1.UnlockList;
    end;

Copy Code

    if( ListFillingThread->WaitFor() ) {
      TList* list = ThreadList1–>LockList();
      for( int i = 0; i < list->Count; i++ ) {
        DoSomething( list->Items[i] );
      }
      ThreadList1–>UnlockList();
    }

To wait for a task to complete

1. Create a TEvent object of global scope.
2. When a thread completes an operation other threads are waiting for, have the thread call TEvent.SetEvent.
3. To turn off the signal, call TEvent.ResetEvent.

The following example is an OnTerminate event handler that uses a global counter in a critical section to keep track of the number of terminating threads. When Counter reaches 0, the handler calls the SetEvent method to signal that all processes have terminated:
Copy Code

    procedure TDataModule.TaskTerminateThread(Sender: TObject);
    begin
      ...
      CounterGuard.Acquire; {obtain a lock on the counter}
      Dec(Counter); {decrement the global counter variable}
      if Counter = 0 then
        Event1.SetEvent; {signal if this is the last thread}
      Counter.Release; {release the lock on the counter}
      ...
    end;

Copy Code

    void __fastcall TDataModule::TaskThreadTerminate( TObject *Sender ) {
      ...
      CounterGuard->Acquire(); // lock the counter
      if( ––Counter == 0 )      // decrement counter
        Event1–>SetEvent();    // signal if this is the last thread
      CounterGuard->Release(); // release lock
    }

The main thread initializes Counter, launches the task threads, and waits for the signal that they are all done by calling the TEvent::WaitFor method. WaitFor waits a specified time period for the signal to be set and returns one of the values in the table below.

The following code example shows how the main thread launches the task threads and resumes when they have completed.

Copy Code

    Event1.ResetEvent; {clear the event before launching the threads}
    for i := 1 to Counter do
      TaskThread.Create(False); {create and launch the task threads}
    if Event1.WaitFor(20000) <> wrSignaled then
      raise Exception;
    {continue with main thread}

Copy Code

    Event1–>ResetEvent();  // clear the event before launching threads
    for( int i = 0; i < Counter; i++ ) {
      new TaskThread( false );
    if( Event1–>WaitFor(20000) != wrSignaled )
      throw Exception;
    // now continue with the main thread

Note: If you do not want to stop waiting for an event handler after a specified time period, pass the WaitFor method a parameter value of INFINITE. Be careful when using INFINITE, because your thread will hang if the anticipated signal is never received.
To check if another thread is waiting on your thread to terminate

1. In your Execute procedure, implement the Terminate method by checking and responding to the Terminated property.
2. This is one way to code the logic:

Copy Code

    procedure TMyThread.Execute;
    begin
      while not Terminated do
        PerformSomeTask;
    end;

Copy Code

    void __fastcall TMyThread::Execute() {
      while( !Terminated )
        DoSomething();
    }

WaitFor return values

Value | Meaning
wrSignaled | The signal of the event was set.
wrTimeout | The specified time elapsed without the signal being set.
wrAbandoned | The event object was destroyed before the timeout period elapsed.
wrError | An error occurred while waiting.

See Also

VCL Overview

Writing the Thread Function

Using the Main VCL Thread

Avoiding Simultaneous Thread Access to the Same Memory

Handling Exceptions

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!