一定の時間間隔でサーバーへの接続をチェックするスレッドをバックグラウンドで実行したいと思います。たとえば、5秒ごと。
これに適した「デザインパターン」があるかどうかわかりませんか?私が正しく覚えているなら、executeメソッドでスリープしているスレッドは良くないことをどこかで読んだことがあります。しかし、私は間違っているかもしれません。
また、通常のTThreadクラスまたはOTLスレッドライブラリを使用できます。
何か案は?
ありがとう。
一定の時間間隔でサーバーへの接続をチェックするスレッドをバックグラウンドで実行したいと思います。たとえば、5秒ごと。
これに適した「デザインパターン」があるかどうかわかりませんか?私が正しく覚えているなら、executeメソッドでスリープしているスレッドは良くないことをどこかで読んだことがあります。しかし、私は間違っているかもしれません。
また、通常のTThreadクラスまたはOTLスレッドライブラリを使用できます。
何か案は?
ありがとう。
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 ディスパッチャーは、最も優先度の高いタイマーの適切なタイムアウト値を指定します。
イベントを使用して、タイムアウトを指定し、イベントを待機するループによって子孫のExecute
メソッドを実装できます。そうすれば、必要なときに、たとえば終了するときに、スレッドをすぐにウェイクアップできます。TThread
WaitForSingleObject
5秒のイベントを達成する別の手段を追加するには、TTimerに似ていますが、アプリケーションに依存しないマルチメディアタイマーを使用できます。構成後(ワンショットまたは反復を設定できます)、別のスレッドにコールバックします。その性質上、非常に正確です(1ms以内)。ここでいくつかのサンプルDelphiコードを参照してください。
タイマーを呼び出すコードは単純で、すべてのWindowsプラットフォームでサポートされています。
スレッドがアプリの存続期間中実行され、アプリの終了時に OS によって単純に終了される可能性があり、正確なタイミングを必要としない場合、スリープ (5000) よりも多くの入力を必要とするソリューションに悩む必要はありません。