Delphi TThread处理错误

时间:2018-06-30 16:52:58

标签: delphi delphi-10.2-tokyo

我正在阅读“ Delphi高性能”,并且缺少某些内容。给出此代码作为测试:

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运行代码,则会出现此错误:

enter image description here

我也阅读了更多有关delphi的编码,并且我看到Nick Hodges刚刚打电话给Terminate;。调用Terminate;是否足以安全地停止线程?请注意,我已设置FreeOnTerminate := true,所以我不必关心对象的死亡。终止应停止执行(execute内部是什么),因此应像这样:

  • 呼叫终止
  • 执行停止
  • 线程停止执行
  • 线程现在是免费的(FreeOnTerminate:= true)

请告诉我我想念的东西。


注意。 在这本书中,该线程没有FreeOnTerminate := true。因此,该线程需要手动释放。我想这就是他打电话的原因

thread.Terminate;
thread.WaitFor;
FreeAndNil(thread)

我同意Terminate(停止thread =和FreeAndNil(手动释放对象),但是需要WaitFor?

1 个答案:

答案 0 :(得分:8)

  

请告诉我我想念的东西。

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

这包括您的WaitFor调用,该调用将对可能已经释放的对象起作用。这种“无用后使用”可能会触发上述错误,以及其他更多“有趣”的行为。