TThread.OnTerminate executing thread

846 Views Asked by At

The Delphi help for TThread.OnTerminate states that:

The method assigned to the OnTerminate event is executed in the context of the main thread rather than the context of the thread being terminated.

Is this even the case when the thread is created in another thread than the main thread?

So, is the OnTerminate called in the thread that created the TThread, or is it called in main thread? The IDE does not tells me this. When I debug, I see no active thread in the OnTerminate event. :-/

1

There are 1 best solutions below

0
On BEST ANSWER

The documentation is correct. The OnTerminate event handler is always run in the main thread by default. Internally, TThread.DoTerminate() (which is called after the thread's Execute() method exits) uses TThread.Synchronize() to call the handler:

function ThreadProc(Thread: TThread): Integer;
var
  ...
begin
  ...
  try
    if not Thread.Terminated then
    try
      Thread.Execute;
    except
      ...
    end;
  finally
    ...
    Thread.DoTerminate;
    ...
  end;
end;

procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;

procedure TThread.CallOnTerminate;
begin
  if Assigned(FOnTerminate) then FOnTerminate(Self);
end;

If you want the OnTerminate handler to run in the context of the terminating thread (or any other thread you want), you can simply override DoTerminate() to call the handler however you want, eg:

type
  TMyThread = class(TThread)
    ...
  protected
    ...
    procedure Execute; override;
    procedure DoTerminate; override;
    ...
  end;

procedure TMyThread.Execute;
begin
  ...
end;

procedure TMyThread.DoTerminate;
begin
  // do whatever you want here, but DON'T call inherited!
  if Assigned(OnTerminate) then OnTerminate(Self);
end;