代码之家  ›  专栏  ›  技术社区  ›  Raffaele Rossi

delphi tthread handle错误

  •  0
  • Raffaele Rossi  · 技术社区  · 6 年前

    我正在读“德尔福高性能”,有一些东西是我遗漏了。将此代码作为测试:

    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; 但读了这本书,我发现普里莫兹停止了这样一条线索:

    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; 是的。正在呼叫 终止; 足以安全地阻止线程?注意我已经设置了 FreeOnTerminate := true 所以我 不要 关心物体的死亡。终止应该停止执行(execute中的内容),因此应该如下所示:

    • 呼叫已终止
    • 执行停止
    • 线程停止执行
    • 线程现在是空闲的(freeonterminate:=true)

    请告诉我我遗漏了什么。


    注意。 在书中没有线索 FreeOnTerminate:=真 .所以线程需要手动释放;我想这就是他调用

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

    我同意终止(停止线程=和freeandnil(手动释放对象),但是waitfor?

    1 回复  |  直到 6 年前
        1
  •  8
  •   Turbo J    6 年前

    请告诉我我遗漏了什么。

    文件 FreeOnTerminate 明确表示不能在 任何 之后 Terminate 是的。

    包括你的 WaitFor 调用,这将对一个可能已经释放的对象起作用。这种在免费后使用的方式会引发上述错误,以及其他更“有趣”的行为。