13

一定の時間間隔でサーバーへの接続をチェックするスレッドをバックグラウンドで実行したいと思います。たとえば、5秒ごと。

これに適した「デザインパターン」があるかどうかわかりませんか?私が正しく覚えているなら、executeメソッドでスリープしているスレッドは良くないことをどこかで読んだことがあります。しかし、私は間違っているかもしれません。

また、通常のTThreadクラスまたはOTLスレッドライブラリを使用できます。

何か案は?

ありがとう。

4

5 に答える 5

16

OmniThreadLibraryでは、次のようにします。

uses
  OtlTask,
  OtlTaskControl;

type
  TTimedTask = class(TOmniWorker)
  public
    procedure Timer1;
  end;

var
  FTask: IOmniTaskControl;

procedure StartTaskClick;
begin
  FTask := CreateTask(TTimedTask.Create())
    .SetTimer(1, 5*1000, @TTimedTask.Timer1)
    .Run;
end;

procedure StopTaskClick;
begin
  FTask.Terminate;
  FTask := nil;
end;

procedure TTimedTask.Timer1;
begin
  // this is triggered every 5 seconds
end;

Execute でのスリープについては、その方法によって異なります。スリープを使用する場合、これはあまり賢明ではない可能性があります (たとえば、スリープ中にスレッドが停止するのを防ぐため)。WaitForSingleObject でスリープしても問題ありません。

TThread と WaitForSingleObject の例:

type
  TTimedThread = class(TThread)
  public
    procedure Execute; override;
  end;

var
  FStopThread: THandle;
  FThread: TTimedThread;

procedure StartTaskClick(Sender: TObject);
begin
  FStopThread := CreateEvent(nil, false, false, nil);
  FThread := TTimedThread.Create;
end;

procedure StopTaskClick(Sender: TObject);
begin
  SetEvent(FStopThread);
  FThread.Terminate;
  FThread.Free;
  CloseHandle(FStopThread);
end;

{ TTimedThread }

procedure TTimedThread.Execute;
begin
  while WaitForSingleObject(Form71.FStopThread, 5*1000) = WAIT_TIMEOUT do begin
    // this is triggered every 5 seconds
  end;
end;

OTL タイマーの実装は、上記の TThread コードに似ています。OTL タイマーは優先度リストに保持され (基本的に、タイマーは「次の発生」時間でソートされます)、TOmniWorker の内部 MsgWaitForMultipleObjects ディスパッチャーは、最も優先度の高いタイマーの適切なタイムアウト値を指定します。

于 2011-12-07T09:09:42.270 に答える
14

イベントを使用して、タイムアウトを指定し、イベントを待機するループによって子孫のExecuteメソッドを実装できます。そうすれば、必要なときに、たとえば終了するときに、スレッドをすぐにウェイクアップできます。TThreadWaitForSingleObject

于 2011-12-07T08:38:40.730 に答える
1

5秒のイベントを達成する別の手段を追加するには、TTimerに似ていますが、アプリケーションに依存しないマルチメディアタイマーを使用できます。構成後(ワンショットまたは反復を設定できます)、別のスレッドにコールバックします。その性質上、非常に正確です(1ms以内)。ここでいくつかのサンプルDelphiコードを参照してください。

タイマーを呼び出すコードは単純で、すべてのWindowsプラットフォームでサポートされています。

于 2011-12-07T10:11:35.677 に答える
1

スレッドがアプリの存続期間中実行され、アプリの終了時に OS によって単純に終了される可能性があり、正確なタイミングを必要としない場合、スリープ (5000) よりも多くの入力を必要とするソリューションに悩む必要はありません。

于 2011-12-07T10:08:24.907 に答える
0

CreateWaitableTimerSetWaitableTimerを使用する

于 2011-12-07T09:23:41.947 に答える