自动或手动释放TThread [英] Free a TThread either automatically or manually

查看:136
本文介绍了自动或手动释放TThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序中有一个主线程和一个单独的线程.如果单独的线程在主线程之前完成,则它应自动释放自己.如果主线程先完成,则应释放单独的线程.

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 calling Terminate() 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆