私はいくつかのTTimer.OnTimerイベントで6つの匿名スレッドを生成するDelphiアプリケーションを持っています。アプリケーション終了時にDelphiで匿名スレッドを終了するにはどうすればよいですか?
タイトルバーのXボタンからアプリケーションを閉じると、アドレス$ C0000005のアクセス違反が発生し、FastMMはTAnonymousThreadオブジェクトを漏洩したと報告します。
TThread.CreateAnonymousThread()メソッドを使用してOnTimerイベント内で作成されたDelphiで匿名スレッドを解放する最も良い方法は何ですか?私のために働いた
SOLUTION:
無料-EDされると、それらを終了し、匿名のスレッドのラッパーを作成しました。ここ
type
TAnonumousThreadPool = class sealed(TObject)
strict private
FThreadList: TThreadList;
procedure TerminateRunningThreads;
procedure AnonumousThreadTerminate(Sender: TObject);
public
destructor Destroy; override; final;
procedure Start(const Procs: array of TProc);
end;
{ TAnonumousThreadPool }
procedure TAnonumousThreadPool.Start(const Procs: array of TProc);
var
T: TThread;
n: Integer;
begin
TerminateRunningThreads;
FThreadList := TThreadList.Create;
FThreadList.Duplicates := TDuplicates.dupError;
for n := Low(Procs) to High(Procs) do
begin
T := TThread.CreateAnonymousThread(Procs[n]);
TThread.NameThreadForDebugging(AnsiString('Test thread N:' + IntToStr(n) + ' TID:'), T.ThreadID);
T.OnTerminate := AnonumousThreadTerminate;
T.FreeOnTerminate := true;
FThreadList.LockList;
try
FThreadList.Add(T);
finally
FThreadList.UnlockList;
end;
T.Start;
end;
end;
procedure TAnonumousThreadPool.AnonumousThreadTerminate(Sender: TObject);
begin
FThreadList.LockList;
try
FThreadList.Remove((Sender as TThread));
finally
FThreadList.UnlockList;
end;
end;
procedure TAnonumousThreadPool.TerminateRunningThreads;
var
L: TList;
T: TThread;
begin
if not Assigned(FThreadList) then
Exit;
L := FThreadList.LockList;
try
while L.Count > 0 do
begin
T := TThread(L[0]);
T.OnTerminate := nil;
L.Remove(L[0]);
T.FreeOnTerminate := False;
T.Terminate;
T.Free;
end;
finally
FThreadList.UnlockList;
end;
FThreadList.Free;
end;
destructor TAnonumousThreadPool.Destroy;
begin
TerminateRunningThreads;
inherited;
end;
エンドは、あなたがそれを呼び出すことができる方法です。
procedure TForm1.Button1Click(Sender: TObject);
begin
FAnonymousThreadPool.Start([ // array of procedures to execute
procedure{anonymous1}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot1.png', 'c:\1.jpg');
finally
Http.Free;
end;
end,
procedure{anonymous2}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot2.png', 'c:\2.jpg');
finally
Http.Free;
end;
end
]);
end;
ませんメモリリーク、適切なシャットダウンと使いやすいです。
'匿名スレッド' - 大変です。エンバカデロが今私たちに求めてきたことは? –
@マルティン:何も怖い、本当に。これは、作成時に匿名メソッドによって動作が提供されるスレッドです。スレッドを定義するときにクロージャを使用できます。 –
スレッドを継続的に作成/破棄しています。過去20年を費やして、開発者に避けるよう指示してきました。それにもかかわらず、実際に開始されていない場合、私はなぜAVがあるべきかを見ることができません。 –