delphi中的线程初始化和清理

Pet*_*ner 7 delphi multithreading soap

我正在阅读另一个问题的答案,这个问题是关于需要进行初始化和建议连接到ADO对象的必要性.我需要做一些类似于在线程中执行soap调用的操作.

有没有办法覆盖TThread对象,以便在线程内执行之前和之后自动运行?

对于这个例子,我们正在转换为SOAP后端,并且必须做大量的事情,它可以节省一些时间来覆盖新的SOAP友好的TThread而不是为每个线程添加coinitialize和couninitialze.但一般来说,初始化清理线程内部的线程有时似乎是个好主意.现在看起来你只能做一个或另一个.

Dav*_*nan 8

也许你想要这样的东西:

type
  TMyThread = class sealed(TThread)
  private
    FOnBeforeExecute: TProc;
    FOnExecute: TProc;
    FOnAfterExecute: TProc;
  protected
    procedure Execute; override;
  public
    property OnBeforeExecute: TProc read FOnBeforeExecute write FOnBeforeExecute;
    property OnExecute: TProc read FOnExecute write FOnExecute;
    property OnAfterExecute: TProc read FOnAfterExecute write FOnAfterExecute;
  end;

procedure TMyThread.Execute;
begin
  if Assigned(OnBeforeExecute) then
    OnBeforeExecute;
  try
    if Assigned(OnExecute) then
      OnExecute;
  finally
    if Assigned(OnAfterExecute) then
      OnAfterExecute;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我把它变成了一个密封的类,所以你不能用Execute破坏设计的东西代替它.额外的好处是您可以使用事件将线程过程与实现类分离.

  • @TLama只是将你的建议作为答案发布,让投票决定. (2认同)

Mar*_*ema 5

如果你想要注意特定的初始化和最终化,那么使用像David这样的事件来回答意味着你必须为你创建的每个线程分配这些事件.这意味着要么添加特定的构造函数来传递它们,要么以挂起模式创建线程.

就个人而言,我真的不想记住做所有这些事情,因此会寻求更多态的解决方案:

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;
Run Code Online (Sandbox Code Playgroud)

需要做Ole Stuff的线程可以有一个共同的基础来处理初始化和最终化:

type
  TOleThread = class(TInitializeFinalizeThread)
  protected
    procedure InitializeExecution; override;
    procedure FinalizeExecution; override;
  end;

procedure TOleThread.InitializeExecution;
begin
  CoInitialize;
end;

procedure TOleThread.FinalizeExecution;
begin
  CoUninitialize;
end;
Run Code Online (Sandbox Code Playgroud)

这意味着实际上要执行某些操作的类可以继承TOleThread并确保初始化和终结已经完成,因此它们只需要覆盖InternalExecute.

type
  TWordMailMergeThread = class(TInitializeFinalizeThread)
  protected
    procedure InternalExecute; override;
  end;

procedure TWordMailMergeThread.InternalExecute;
begin
  // Whatever you need this to do.
end;
Run Code Online (Sandbox Code Playgroud)

虽然他们当然可以自由地覆盖InitializeExecutionFinalizeExecution设置方法并退出与OleServer的连接(在本例中为Word),而不是在中InternalExecute.