关闭应用程序后获取泄漏报告(Tsrch_slave_thread,TSimpleEvent)。我理解应用程序退出之前,线程可以释放自己,但如何避免?如何等待线程完成?
谢谢。
工作线程的定义>>
- FreeOnTerminate设置为true
- OnTerminate:TMaster.slvsrch_termination();
Tsrch_slave_thread = class(TThread)
private
FSW: TStopWatch;
protected
procedure Execute; override;
public
SimpleEvent: TSimpleEvent;
master: TMaster;
master_HWND: HWND;
procedure DoTerminate; override;
constructor Create;
destructor Destroy; override;
end;
procedure Tsrch_slave_thread.Execute;
var
text_orig: string;
activesearch: integer;
begin
FSW.Start;
while not terminated do begin
activesearch := master.CMD_LISTCNT;
//stopper refresh
synchronize(procedure begin
with self.master do
Fmasternode.text := FmasterDat.MstrName + ' (' + floattostr(Fsw.ElapsedMilliseconds / 1000) + 'sec - Searching)';
end);
if (SimpleEvent.WaitFor(2000) <> wrTimeOut) or (activesearch <> 1) then break;
end;
FSW.Stop;
end;
TMaster(持有工作线程的参考)&gt;&gt;
TMaster = class(TObject)
private
...
Fslave_search_thread : Tsrch_slave_thread;
...
public
...
end;
TMaster的析构函数(我从这里设置工作线程的终止标志)&gt;&gt;
destructor TMaster.Destroy;
begin
FSlaveList.free;
DeallocateHWnd( fMsgHandlerHWND );
if assigned( self.Fslave_search_thread ) then self.Fslave_search_thread.terminate;
inherited;
end;
在主窗体的OnClose事件处理程序中释放TMaster实例&gt;&gt;
procedure TfrmCLmain.FormClose(Sender: TObject; var Action: TCloseAction);
...
node := frmDevTree.JvTreeView1.Items.GetFirstNode;
if node.data <> nil then
begin
while Assigned(Node) do begin
if TObject(node.data) is TMaster then
TMaster(node.data).free;
node := node.getNextSibling;
end;
end;
...
freeandnil(udpsend);
action := caFree;
end;
Tsrch_slave_thread的析构函数&gt;&gt;
destructor Tsrch_slave_thread.destroy;
begin
self.SimpleEvent.free;
inherited;
end;
Tsrch_slave_thread.DoTerminate&gt;&gt;
procedure Tsrch_slave_thread.DoTerminate;
begin
inherited;
self.master.FlastSearchTime := self.FSW.ElapsedMilliseconds / 1000;
self.simpleEvent.SetEvent;
end;
Tsrch_slave_thread的OnTerminate事件处理程序&gt;&gt;
procedure TMaster.slvsrch_termination(Sender: TObject);
begin
if Assigned(Fslave_search_thread) then
begin
self.FLastSearchTime := Fslave_search_thread.FSW.ElapsedMilliseconds - SEARCH_DELAY_SEC;
Fslave_search_thread := nil;
end;
...
postmessage ( self.FMasterDevFrmHND, WM_SLVSRCH_COMPLETE, integer(self), 0);
end;
答案 0 :(得分:1)
简单地说,你需要销毁线程并终止它。终止线程后立即添加对Free
的调用。
destructor TMaster.Destroy;
begin
FSlaveList.free;
DeallocateHWnd(fMsgHandlerHWND);
if assigned(Fslave_search_thread) then
Fslave_search_thread.terminate;
Fslave_search_thread.Free;
inherited;
end;
另外,过度使用Self
会使代码难以阅读。