如何在delphi中释放一个线程

Niy*_*wan 5 delphi multithreading

我问这里有多线程应用程序.我想终止线程,并在调用以下方法时启动一个新线程.

procedure TFRABData.RefreshDataset;
var
  GridUpdater: TGridUpdater;
begin
  if Assigned(updaterThread) and (updaterThread <> nil) then
  begin
    updaterThread.Terminate;
  end;
  GridUpdater := TGridUpdater.Create(True);
  GridUpdater.OwnerForm := Self;
  updaterThread := GridUpdater;
  GridUpdater.FreeOnTerminate := False;
  GridUpdater.Start;
  CodeSite.Send('RefreshDataset executed');
end
Run Code Online (Sandbox Code Playgroud)

但是,当FreeOnTerminate设置为True,我得到访问冲突,但FreeOnTerminate设置为时False,我得到内存泄漏.如何释放线程?

Rem*_*eau 10

你需要调用Terminate(),WaitFor()并且Free()都在一起,如:

procedure TFRABData.RefreshDataset; 
var 
  GridUpdater: TGridUpdater; 
begin 
  if Assigned(updaterThread) then 
  begin 
    updaterThread.Terminate; 
    updaterThread.WaitFor; 
    FreeAndNil(updaterThread); 
  end; 
  GridUpdater := TGridUpdater.Create(True); 
  GridUpdater.OwnerForm := Self; 
  GridUpdater.Start; 
  updaterThread := GridUpdater; 
  CodeSite.Send('RefreshDataset executed'); 
end;
Run Code Online (Sandbox Code Playgroud)

  • 该线程正在使用数据库连接并发布UI更新.如果您只是发信号通知现有线程而不实际等待它,则新线程可能会践踏该线程. (2认同)

NGL*_*GLN 7

除了RRUZ的答案之外,还要让它与之合作FreeOnTerminate = False:

Terminate 只是设置标志,它什么都没做.

更改

  if Assigned(updaterThread) and (updaterThread <> nil) then 
  begin 
    updaterThread.Terminate; 
  end; 
Run Code Online (Sandbox Code Playgroud)

  if Assigned(updaterThread) then 
  begin 
    updaterThread.Free; 
  end; 
Run Code Online (Sandbox Code Playgroud)

Free将调用TerminateWaitFor随后消除您的内存泄漏.

  • -1 NEVER在尚未发出信号的线程上调用`Free()`.不要依赖线程析构函数为你调用`Terminate()`和`WaitFor()`.总是在你自己的代码中明确地调用它们.多年来,许多人通过释放正在运行的线程并让析构函数终止来遇到问题.它只是无法正常工作,并且无论如何都不是处理这个问题的合适场所. (3认同)
  • 已经一次又一次地证明,如果线程仍在运行,则不能依赖`TThread`析构函数**来正确终止线程.大卫和你所暗示的是**危险**.不要依赖它.自己明确终止一个帖子,**然后**释放它. (2认同)

RRU*_*RUZ 5

  1. 避免需要启动挂起的线程
  2. 修改TThread构造函数以接收OwnerForm参数
  3. 在线程的构造函数中设置FreeOnTerminate值.
  4. 在未暂停状态下启动TThread.

这样的事情.

  TGridUpdater = class(TThread)
  private
    FOwnerForm: TForm;
  public
    constructor Create(OwnerForm : TForm); overload;
    destructor Destroy; override;
    procedure Execute; override;
  end;

constructor TGridUpdater.Create(OwnerForm: TForm);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  FOwnerForm:=OwnerForm;
end;

destructor TGridUpdater.Destroy;
begin

  inherited;
end;

procedure TGridUpdater.Execute;
begin
  //your code goes here

end;
Run Code Online (Sandbox Code Playgroud)

现在你可以用这种方式创建你的Tthread

GridUpdater:=TGridUpdater.Create(Self); //Just set it and forget it
Run Code Online (Sandbox Code Playgroud)