启动后,Delphi将线程设置为nil

时间:2017-02-11 23:28:40

标签: multithreading delphi

今天我错过了一课,我发现了一段我无法理解的奇怪的代码。这是班级:

type
 TMemoMessageThread = class(TThread)
  strict private
   FMemo: TMemo;
   FMemoMessage: string;
  protected
   procedure Execute; override;
  public
   constructor Create(aMemo: TMemo);
   property MemoMessage: string read FMemoMessage write FMemoMessage;
 end;

这里我创建了一个从TThread下降的类,因为我想模拟一个繁重的计算。看看非常简单的用户界面。

enter image description here

点击Button2"创建暂停"创建一个Suspended线程,然后按Button3使用该线程。这是代码:

constructor TMemoMessageThread.Create(aMemo: TMemo);
begin

 if (aMemo = nil) then
  raise Exception.Create('tMemo non valid!!!');

 inherited Create(True);
 FreeOnTerminate := True;
 FMemo := aMemo;

end;

procedure TMemoMessageThread.Execute;
begin

 Synchronize(procedure
             begin
              FMemo.Lines.Add('... process in parallel thread ...');
             end);

 Sleep(7000); //simulate something heavy to compute

 Synchronize(procedure
             begin
              FMemo.Lines.Add(FMemoMessage + '. Done! :)');
             end);

end;

procedure TForm1.Button2Click(Sender: TObject);
begin

 MemoMessageThread := TMemoMessageThread.Create(Memo1);
 MemoMessageThread.MemoMessage := 'Hello from TMemoMessageThread';
 Button3.Enabled := true;

end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 MemoMessageThread.Start;
 MemoMessageThread := nil; //why nil after start?
end;

正如你所看到的,为什么开始后会有一个零?我真的无法理解。既然FreeOnTerminate我不应该忽略那条线?

2 个答案:

答案 0 :(得分:6)

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Matteo Notes</title> <link rel="stylesheet" href="C:\Users\User\Desktop\Dash\Notes\style.css"> <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script> </head> <body> <input type="text" placeholder="Add..."> <button class="add">Add</button> <button class="remove">Remove</button> <script src="script.js" type="text/javascript"></script> </body> </html>设置为MemoMessageThread会删除对实例化对象的引用。对象仍然存在并执行,但与对象的联系丢失。

由于线程是使用nil创建的,因此无论如何都不应使用对象的引用。这是将其设置为FreeOnTerminate的唯一目的,我可以看到。

答案 1 :(得分:4)

在这个有限的例子的范围内,确实没有必要参考。尽管如此,它并没有造成任何伤害。

该线程是使用nil set创建的,这意味着一旦启动,您就不能再次访问其任何属性,因为该线程可能已被终止并释放。 Nil-ling引用确保您不能这样做,因此这不是一个坏主意,但只要您记得不访问已启动的线程实例,就没有必要。