- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在给定的示例中,我在调用AThread.Free.
时收到异常
program Project44;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Windows;
type
TMyException = class(Exception);
var
AThread: TThread;
begin
AThread := TThread.Create(True);
try
AThread.FreeOnTerminate := True;
//I want to do some things here before starting the thread
//During the setup phase some exception might occur, this exception is for simulating purpouses
raise TMyException.Create('exception');
except
AThread.Free; //Another exception here
end;
end.
AThread
的TThread
实例? TThread.Destroy
在销毁自身之前先调用Resume
。这有什么意义呢? 最佳答案
您不能在线程实例上将FreeOnTerminate
设置为True
,并且调用Free
。您必须做一个或另一个,但不能两者都做。就目前而言,您的代码两次破坏了线程。您绝不能破坏对象两次,当然,当析构函数第二次运行时,会发生错误。
这里发生的是,由于您创建了挂起的线程,因此在您明确释放线程之前,什么也不会发生。当您执行此操作时,析构函数将继续执行线程,等待其完成。然后,这会导致再次调用Free
,因为您将FreeOnTerminate
设置为True
。第二次调用Free
将关闭句柄。然后返回线程proc并调用 ExitThread
。由于线程的句柄已关闭,因此失败。
正如Martin在评论中指出的那样,由于TThread
方法是抽象的,因此您不能直接创建TThread.Execute
。另外,您不应使用已弃用的Resume
。使用Start
开始执行挂起的线程。
我个人不喜欢使用FreeOnTerminate
。使用此功能会导致线程在与创建线程不同的线程上被破坏。当您想忘记实例引用时,通常使用它。这样一来,您就无法确定线程在进程终止时是否已被销毁,甚至在进程终止期间是否正在终止并释放自身。
如果必须使用FreeOnTerminate
,则需要确保在将Free
设置为FreeOnTerminate
之后不要调用True
。因此,显而易见的解决方案是在调用FreeOnTerminate
之后立即将True
设置为Start
,然后忽略线程实例。如果在准备开始之前有任何异常,则可以安全地释放线程,因为此时FreeOnTerminate
仍将是False
。
Thread := TMyThread.Create(True);
Try
//initialise thread object
Except
Thread.Free;
raise;
End;
Thread.FreeOnTerminate := True;
Thread.Start;
Thread := nil;
TMyThread
构造函数中。然后代码如下所示:
Thread := TMyThread.Create(True);
Thread.FreeOnTerminate := True;
Thread.Start;
Thread := nil;
关于delphi - 线程错误: The Handle is Invalid (6) when trying to Free a suspended thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42364186/
我是一名优秀的程序员,十分优秀!