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)
请告诉我我遗漏了什么。
注.
书中的线程没有FreeOnTerminate := true
。所以需要手动释放线程;我想这就是他打电话给
的原因
thread.Terminate;
thread.WaitFor;
FreeAndNil(thread)
我同意终止(停止线程=和 FreeAndNil(手动释放对象)但 WaitFor?
Please tell me what I'm missing.
FreeOnTerminate
的文档明确指出您不能在 Terminate
之后以 任何 方式使用线程。
这包括您的 WaitFor
调用,它适用于可能已经释放的对象。这种 use-after-free 可以触发上述错误,以及其他更多 "interesting" 行为。
我正在阅读 "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)
请告诉我我遗漏了什么。
注.
书中的线程没有FreeOnTerminate := true
。所以需要手动释放线程;我想这就是他打电话给
thread.Terminate;
thread.WaitFor;
FreeAndNil(thread)
我同意终止(停止线程=和 FreeAndNil(手动释放对象)但 WaitFor?
Please tell me what I'm missing.
FreeOnTerminate
的文档明确指出您不能在 Terminate
之后以 任何 方式使用线程。
这包括您的 WaitFor
调用,它适用于可能已经释放的对象。这种 use-after-free 可以触发上述错误,以及其他更多 "interesting" 行为。