-1

TThreadクラスから派生した新しいクラスを作成し、コンストラクターで「inherited Create(True);」を呼び出し、Execute()呼び出しをオーバーライドしたため、「Resume()」を呼び出します。次に、Execute()を呼び出します。 )(スレッドを再度実行)クラスインスタンスを破棄せずに、新しいクラス内に「myRestart()」という関数があります。これは「継承されたCreate(True)」を呼び出します。そして、「Resume()」を再度呼び出すことができるようになり、スレッドが再び機能します。

私の質問は、これは安全な方法ですか?このクラスのインスタンスが複数ある場合も機能しますか?またはそれを行うためのより良い方法はありますか?

ありがとう

4

2 に答える 2

4

そのようなことをしているのはやめましょう。スレッドクラスのプロシージャ/関数を複数回実行する場合は、Executeオーバーライドのwhile()ループからそれらを呼び出し、スレッドに信号を送って、上部にある適切なシンクロオブジェクト、セマフォ、またはイベントを使用してコードを実行します。いう:

TmyThread.Execute;
begin
  while true do
  begin
    someEvent.waitFor(INFINITE);
    if terminated then exit;
    doMyProcedure(params);
    doOtherStuff;
  end;
end;
于 2012-11-26T14:03:13.650 に答える
-1

再起動コードを表示する必要があると思いますか?スレッドが終了した場合はExecuteプロシージャであることがわかっているので、OSの状態はDONEに変わり、resumeを再度呼び出すと、実際の個別のスレッドではなく、メインスレッドの関数としてのみそのスレッドが開始されます。

ちなみに、このサンプルコードは必要に応じて使用できます

unit UWorker;

interface

uses Windows, Classes, Contnrs;

type
  TWorkerThread=class;

  TWorkerJob=class
    procedure ExecuteJob(Worker: TWorkerThread); virtual; abstract;
  end;

  TWorkerThread=class(TThread)
  private
    FFinished: TObjectList;
    FNotFinished: TObjectList;
  protected
    procedure Execute;Override;
  public
    constructor Create(createSuspended: Boolean);override;
    destructor Destroy; override;
  public
    property Finished: TObjectList read FFinished;
    property NotFinished: TObjectList read FNotFinished;
  end;



implementation

{ TWorkerThread }

constructor TWorkerThread.Create(createSuspended: Boolean);
begin
  inherited;
  FFinished := TObjectList.Create;
  FNotFinished := TObjectList.Create;
end;

destructor TWorkerThread.Destroy;
begin
  FFinished.Free;
  FNotFinished.Free;
  inherited;
end;

procedure TWorkerThread.Execute;
var
  CurrentJob: TWorkerJob;
begin
  while not Terminated do
  begin
    if FNotFinished.Count > 0 then
    begin
      CurrentJob := TWorkerJob(FNotFinished.Items[0]);
      FNotFinished.Extract(CurrentJob);

      with CurrentJob do
      begin
        ExecuteJob(Self);
      end;
      FFinished.Add(CurrentJob);
    end else
    begin
      // pass the cpu to next thread or process
      Sleep(5);
    end;
  end;

end;

end.

このコードを使用するには、ワーカーを作成してから、ジョブのインスタンスを作成し、それらをNotFinishedリストに追加します。ワーカーはすべてのジョブを1つずつ実行します。ジョブを再開するには、完了リストからジョブを抽出して、NotFinishedに再度追加します。

ジョブを継承し、ExecuteJobプロシージャをオーバーライドする必要があることを忘れないでください。

于 2012-11-26T10:19:21.723 に答える