自动或手动释放TThread [英] Free a TThread either automatically or manually
问题描述
我的程序中有一个主线程和一个单独的线程.如果单独的线程在主线程之前完成,则它应自动释放自己.如果主线程先完成,则应释放单独的线程.
I have a main thread and a separate thread in my program. If the separate thread finishes before the main thread, it should free itself automatically. If the main thread finishes first, it should free the separate thread.
我了解FreeOnTerminate,并且我读到您必须小心使用它.
I know about FreeOnTerminate, and I've read that you have to be careful using it.
我的问题是,以下代码正确吗?
My question is, is the following code correct?
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;
推荐答案
您可以将其简化为:
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;
说明:
-
要么使用
FreeOnTerminate
要么手动释放线程,但不要同时执行.线程执行的异步特性意味着您可能会面临无法释放线程或两次执行(更糟糕的是)的风险.在执行完之后,将线程对象保留在周围没有风险,并且在已经完成的线程上调用Terminate()
也没有风险.
Either use
FreeOnTerminate
or free the thread manually, but never do both. The asynchronous nature of the thread execution means that you run a risk of not freeing the thread or (much worse) doing it twice. There is no risk in keeping the thread object around after it has finished the execution, and there is no risk in callingTerminate()
on a thread that has already finished either.
不需要同步对仅从一个线程写入而从另一个线程读取的布尔值的访问.在最坏的情况下,您得到的值是错误的,但是由于异步执行,无论如何都是虚假的结果.同步仅对于无法自动读取或写入的数据是必需的.而且,如果您需要同步,请不要使用Synchronize()
.
There is no need to synchronize access to a boolean that is only written from one thread and read from another. In the worst case you get the wrong value, but due to the asynchronous execution that is a spurious effect anyway. Synchronization is only necessary for data that can not be read or written to atomically. And if you need to synchronize, don't use Synchronize()
for it.
不需要像MyThreadReady
这样的变量,因为您可以使用
There is no need to have a variable similar to MyThreadReady
, as you can use WaitForSingleObject()
to interrogate the state of a thread. Pass MyThread.Handle
as the first and 0
as the second parameter to it, and check whether the result is WAIT_OBJECT_0
- if so your thread has finished execution.
顺便说一句:不要使用OnClose
事件,而应使用OnDestroy
.前者不一定要调用,在这种情况下,您的线程可能会继续运行,并使您的进程保持活动状态.
BTW: Don't use the OnClose
event, use OnDestroy
instead. The former isn't necessarily called, in which case your thread would maybe continue to run and keep your process alive.
这篇关于自动或手动释放TThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!