7

我在这里阅读了另一个问题的答案,关于需要运行 coinitialize 和 couninitialize 以连接到 ADO 对象。我需要做一些类似的事情来在线程中执行肥皂调用。

有没有办法覆盖 TThread 对象以在线程内部执行之前和之后自动运行某些东西?

对于此示例,我们正在转换为 SOAP 后端,并且必须做大量的工作,与向每个线程添加 coinitialize 和 couninitialze 相比,仅覆盖一个新的 SOAP 友好 TThread 会节省一些时间。但总的来说,初始化清理线程内部的线程有时似乎是个好主意。现在看来你只能做一个或另一个。

4

2 回答 2

9

也许你想要这样的东西:

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;

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

于 2013-10-04T12:59:35.133 回答
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;

需要执行 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;

这意味着实际上要做某事的类可以继承自TOleThread并确保初始化和终结已经被处理,因此它们只需要覆盖InternalExecute.

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

procedure TWordMailMergeThread.InternalExecute;
begin
  // Whatever you need this to do.
end;

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

于 2013-10-04T17:27:34.340 回答