こんにちは私のフォームでは、実行時にTFrameを作成します。このフレームで、エンドレスループでコマンドを実行するバックグラウンドスレッドを作成します。しかし、このフレームを破棄するときは、このスレッドを破棄する必要があります。やってみます
thread.Suspend;
thread.Terminate;
FreeAndNil(thread);
しかし、AVとThreadErrorを取得します。スレッドを破棄するにはどうすればよいですか?
こんにちは私のフォームでは、実行時にTFrameを作成します。このフレームで、エンドレスループでコマンドを実行するバックグラウンドスレッドを作成します。しかし、このフレームを破棄するときは、このスレッドを破棄する必要があります。やってみます
thread.Suspend;
thread.Terminate;
FreeAndNil(thread);
しかし、AVとThreadErrorを取得します。スレッドを破棄するにはどうすればよいですか?
Execute
スレッドを適切に終了するには、スレッドがそのメソッドを終了していることを確認する必要があります。
コードは次のようになります。
procedure TThread.Execute;
begin
while not Self.Terminated do
begin
//do something
end;
end;
スレッドを破棄する場合は、これを呼び出します。
thread.Terminate;
thread.WaitFor;
FreeAndNil(thread);
tthreadでsuspendを呼び出すのは安全ではありません。また、resumeは、中断して作成されたスレッドを開始するためにのみ使用する必要があります。
Delphi 2010では、これを強化するために、減価償却された場所での一時停止と再開、およびメソッド開始が導入されました。
より完全な説明については 、Codegearsフォーラムのこのスレッドを参照してください。
とは言っても、tthreadを終了して解放する方法は2つあります。
1:スレッドの作成時にFreeOnTerminateを設定したので、呼び出すだけです。
Thread.Terminate;
2:スレッドを解放する前と終了した後、パブリックプロパティから結果を読み取る必要があるため、スレッドを明示的に解放します。
Thread.Terminate;
Thread.WaitFor;
//Do somthing like read a public property from thread object
if Thread <> nil then FreeAndNil(Thread);
メインの実行ループでは、例外処理を入れることをお勧めします。または、スレッドが自分自身を終了しているように見える理由がわからない場合があります。スレッドがFreeOnTerminateに設定されていて、それを解放しようとしたときにすでに解放されている場合、これがAVの原因である可能性があります。
procedure TThread.Execute;
begin
while not Terminated do
begin
try
//do something
except
on E:Exception do
//handle the exception
end;
end;
end;
するだけで十分ですthread.Terminate
。ただし、thread.FreeOnTerminate := true
作成時に設定することをお勧めします。
もちろん、スレッドのタイト ループ (つまりExecute
) では、スレッドの終了が要求されているかどうかを確認する必要があります (Terminated
プロパティを確認します)。スレッドの終了が要求されていることがわかった場合は、単純にループから抜けて を終了しExecute
ます。