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. :-/
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;