Ste*_*eve 9 delphi multithreading delphi-7 tthread
我的程序中有一个主线程和一个单独的线程.如果单独的线程在主线程之前完成,它应该自动释放.如果主线程首先完成,它应该释放单独的线程.
我知道FreeOnTerminate,我读过你必须小心使用它.
我的问题是,以下代码是否正确?
procedure TMyThread.Execute;
begin
... Do some processing
Synchronize(ThreadFinished);
if Terminated then exit;
FreeOnTerminate := true;
end;
procedure TMyThread.ThreadFinished;
begin
MainForm.MyThreadReady := true;
end;
procedure TMainForm.Create;
begin
MyThreadReady := false;
MyThread := TMyThread.Create(false);
end;
procedure TMainForm.Close;
begin
if not MyThreadReady then
begin
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
您可以将其简化为:
procedure TMyThread.Execute;
begin
// ... Do some processing
end;
procedure TMainForm.Create;
begin
MyThread := TMyThread.Create(false);
end;
procedure TMainForm.Close;
begin
if Assigned(MyThread) then
MyThread.Terminate;
MyThread.Free;
end;
Run Code Online (Sandbox Code Playgroud)
说明:
FreeOnTerminate手动使用或释放线程,但绝不要同时使用.线程执行的异步性质意味着您存在不释放线程的风险或(更糟糕的是)执行两次.在完成执行后保持线程对象没有风险,并且调用Terminate()已经完成的线程也没有风险.
无需同步访问仅从一个线程写入并从另一个线程读取的布尔值.在最坏的情况下,您得到了错误的值,但由于异步执行无论如何都是虚假的影响.仅对于无法以原子方式读取或写入的数据,才需要进行同步.如果您需要同步,请不要使用Synchronize()它.
没有必要MyThreadReady使用类似的变量,因为您可以使用它WaitForSingleObject()来查询线程的状态.通过MyThread.Handle作为第一个和0第二个参数给它,并检查结果是否是WAIT_OBJECT_0-如果让你的线程执行结束.
顺便说一句:不要使用该OnClose事件,请OnDestroy改用.前者不一定被调用,在这种情况下,您的线程可能会继续运行并使您的进程保持活动状态.
让主线程为工作线程的 OnTerminate 事件分配一个处理程序。如果工作线程先完成,则处理程序可以向主线程发出信号以释放该线程。如果主线程先完成,它可以终止工作线程。例如:
procedure TMyThread.Execute;
begin
... Do some processing ...
end;
procedure TMainForm.Create;
begin
MyThread := TMyThread.Create(True);
MyThread.OnTerminate := ThreadFinished;
MyThread.Resume; // or MyThread.Start; in D2010+
end;
const
APPWM_FREE_THREAD = WM_APP+1;
procedure TMainForm.ThreadFinished(Sender: TObject);
begin
PostMessage(Handle, APPWM_FREE_THREAD, 0, 0);
end;
procedure TMainForm.WndProc(var Message: TMessage);
begin
if Message.Msg = APPWM_FREE_THREAD then
StopWorkerThread
else
inherited;
end;
procedure TMainForm.StopWorkerThread;
begin
if MyThread <> nil then
begin
MyThread.Terminate;
MyThread.WaitFor;
FreeAndNil(MyThread);
end;
end;
procedure TMainForm.Close;
begin
StopWorkerThread;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5299 次 |
| 最近记录: |