If you want to take care on specific initialization and finalization doing it with events like in David's answer means that you have to assign those events for every thread you create. And that means either adding a specific constructor to pass them in or creating the threads in suspended mode.
Personally I don't really like having to remember to do all those things and would therefore go for a more polymorphic solution:
type
TInitializeFinalizeThread = class(TThread)
protected
procedure InitializeExecution; virtual;
procedure FinalizeExecution; virtual;
procedure InternalExecute; virtual;
procedure Execute; override;
end;
procedure TInitializeFinalizeThread.Execute;
begin
InitializeExecution;
try
InternalExecute;
finally
FinalizeExecution;
end;
end;
Threads needing to do Ole Stuff could then have a common base that takes care of the initialization and finialization:
type
TOleThread = class(TInitializeFinalizeThread)
protected
procedure InitializeExecution; override;
procedure FinalizeExecution; override;
end;
procedure TOleThread.InitializeExecution;
begin
CoInitialize;
end;
procedure TOleThread.FinalizeExecution;
begin
CoUninitialize;
end;
This means that classes that are actually going to do something can just inherit from TOleThread and be assured that the initialization and finalization have been taken care of, so they only need to override InternalExecute.
type
TWordMailMergeThread = class(TInitializeFinalizeThread)
protected
procedure InternalExecute; override;
end;
procedure TWordMailMergeThread.InternalExecute;
begin
// Whatever you need this to do.
end;
Though they are of course free to override the InitializeExecution and FinalizeExecution methods to set up and quit the connection to the OleServer (Word in this example) instead of doing it in the InternalExecute.