Delphi TThread句柄错误

Delphi TThread handle error

我正在阅读 "Delphi High performance",但我缺少一些东西。将此代码作为测试:

type TTest = class(TThread)
  private
    amemo: TMemo;
  public
    constructor Create(ss: boolean; memo: TMemo);
  protected
    procedure Execute; override;
end;

constructor TTest.Create(ss: boolean; memo: TMemo);
begin
  inherited Create(ss);
  FreeOnTerminate := true;
  amemo := memo;
end;

procedure TTest.Execute;
var i: uint32;
begin
  inherited;
  i := 0;

  while not Terminated do
    begin
      Inc(i);
      Synchronize(procedure
                  begin amemo.Lines.Add(i.ToString) end);
      Sleep(1000);
    end;

end;

很简单,这个线程在备忘录中打印了一些数字。我启动线程挂起,所以我必须调用这段代码:

procedure TForm1.Button1Click(Sender: TObject);
begin
  thread := TTest.Create(true, Memo1);
  thread.Start;
end;

我总是停止调用 thread.Terminate; 的线程,但阅读这本书时我看到 Primoz 停止了这样的线程:

procedure TForm1.Button2Click(Sender: TObject);
begin
  thread.Terminate;
  thread.WaitFor; //he adds this method call
  //FreeAndNil(thread)
  //there is the above line as well in the code copied from the book but I have removed it since I have set FreeOnTerminate := true (so I dont have to worry about freeing the obj).
end;

在这一点上,如果我 运行 代码只使用 Terminate 我没有问题。如果我 运行 使用 Terminate + WaitFor 的代码,我会收到此错误:

我也在 delphi 中阅读了更多编码,我看到 Nick Hodges 刚刚调用了 Terminate;。调用 Terminate; 足以安全地停止线程吗?请注意,我设置了 FreeOnTerminate := true 所以我 关心对象的死亡。终止应该停止执行(执行里面的内容)所以它应该是这样的:

请告诉我我遗漏了什么。


注. 书中的线程没有FreeOnTerminate := true。所以需要手动释放线程;我想这就是他打电话给

的原因
thread.Terminate;
thread.WaitFor;
FreeAndNil(thread)

我同意终止(停止线程=和 FreeAndNil(手动释放对象)但 WaitFor?

Please tell me what I'm missing.

FreeOnTerminate 的文档明确指出您不能在 Terminate 之后以 任何 方式使用线程。

这包括您的 WaitFor 调用,它适用于可能已经释放的对象。这种 use-after-free 可以触发上述错误,以及其他更多 "interesting" 行为。