7

ADO オブジェクトに接続するには、coinitialize と couninitialize を実行する必要があるという別の質問への回答を読んでいました。スレッドでソープ呼び出しを実行するには、同様のことを行う必要があります。

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

デビッドの回答のように、特定の初期化とファイナライズをイベントで処理したい場合は、作成するすべてのスレッドにそれらのイベントを割り当てる必要があることを意味します。つまり、特定のコンストラクターを追加してそれらを渡すか、中断モードでスレッドを作成することを意味します。

個人的には、これらすべてのことを覚えておく必要があるのはあまり好きではないので、よりポリモーフィックなソリューションを使用します。

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;

InitializeExecutionもちろん、とメソッドをオーバーライドしFinalizeExecutionて、OleServer (この例では Word) への接続をセットアップして終了することは自由ですが、InternalExecute.

于 2013-10-04T17:27:34.340 に答える