スレッドのExecute
メソッドは、スレッドのTerminated
プロパティの状態を定期的にチェックする必要があります。の場合はTrue
、スレッドExecute
メソッドを終了する必要があります。
したがって、一般的なExecute
方法は次のようになります。
procedure TMyThread.Execute;
begin
while not Terminated do
DoNextPieceOfWork
end;
スレッドにはFActive
、同じタスクを実行している独自のフラグがあるようです。それに関する問題はそれTThread
について知らないということです。FActive
したがって、組み込みのメカニズムを取り除き、代わりに使用する必要があります。
Free
スレッドを呼び出すと、が呼び出されますTerminate
。それはに設定Terminated
されますTrue
。次に、スレッドメソッドが終了するのを待ちます。これは、スレッドがそれを認識して終了するために発生しTerminated
ますTrue
。そして、スレッドのデストラクタは、スレッドを整理する作業を続行して終了できます。
Terminate
あなたの答えのコードを見ると、既存のメカニズムを利用するように書かれたほうがよいでしょう。
type
TMyThread = class(TThread)
private
FTerminateEvent: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(ACreateSuspended: Boolean);
destructor Destroy; override;
end;
constructor TMyThread.Create(ACreateSuspended: Boolean);
begin
inherited Create(ACreateSuspended);
FTerminateEvent := TEvent.Create(nil, True, False, '');
end;
destructor TMyThread.Destroy;
begin
inherited;
FTerminateEvent.Free;
end;
procedure TMyThread.TerminatedSet;
begin
FTerminateEvent.SetEvent;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
// do somthing interesting!
FTerminateEvent.WaitFor(5000);
end;
end;
Stop
これで、別のメソッドは必要ありません。Free
スレッドを呼び出すだけです。その後Terminate
、と呼ばれます。そして、TerminatedSet
と呼ばれます。次に、イベントが通知されます。その後、Execute
終了します。そして、スレッドが消えることができます。
そうは言っても、5000ミリ秒のタイムアウトが最善のアプローチであるシナリオを考えるのに苦労しています。なぜこれをしているのかわかりませんが、スレッドが熱くならないようにスロットルを調整しようとしていると思います。ビジーループを避けたい。それは素晴らしいことですが、固定タイムアウトを使用することはそれを行う方法ではありません。これを行う方法は、同期イベント(通常はイベント)を待機することです。その後、実行する作業が増えると、イベントが通知され、スレッドがウェイクアップします。