在delphi 2007中启动挂起线程的正确方法是什么?

时间:2010-11-17 16:02:56

标签: multithreading delphi delphi-2007

在delphi XE中我可以使用启动过程,但这种方法在delphi 2007中不存在。

此示例代码在delphi xe中正常工作,使用Start

MyThread:=TMyThread.Create(True);
MyThread.FreeOnTerminate    :=True;
MyThread.Property1:=900;
MyThread.Property2:=2;
MyThread.Start;

但是在delphi 2007中,start过程不存在,所以我使用的是在新版本的delphi中不推荐使用的简历过程。

MyThread:=TMyThread.Create(True);
MyThread.FreeOnTerminate    :=True;
MyThread.Property1:=900;
MyThread.Property2:=2;
MyThread.Resume;

所以quieon是,在delphi 2007中可以使用resume,或者我必须使用其他方式来启动一个被挂起的线程?

提前致谢。

5 个答案:

答案 0 :(得分:21)

启动挂起线程的正确方法是首先不要有挂起的线程。

有一种更好的方法来创建线程。如果调用者必须为对象提供值以使该类正常工作,那么不要使其成为可选:要求它作为构造函数的参数。如果该参数只有一个有效值,那么甚至不要将它作为参数:只需在构造函数中对其进行硬编码即可。 (你有多少次写过一个线程类,只有有时应该在终止时释放自己?我从未见过它。)

constructor TMyThread.Create(Prop1, Prop2: Integer);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  Property1 := Prop1;
  Property2 := Prop2;
end;

然后你可以使用Ron Popeil创建线程的方法:只需设置并忘记它!

MyThread := TMyThread.Create(900, 2);

调用者在创建线程后不必对线程执行任何操作。由于它是一个免费终止的线程,调用者可能根本不应该保留对MyThread变量的引用,因为一旦线程完成运行,引用就会变为无效。

(担心inherited Create(False)行创建一个线程,它将在构造函数的其余部分完成运行之前开始运行?不要!这已经在十年前的Delphi 6中修复了。在构造函数完成后自动启动;请参阅TThread.AfterConstruction以了解如何。)

答案 1 :(得分:5)

在构造函数中将CreateSuspended参数设置为true创建的线程上调用Resume没有任何问题。 (为什么还有一个CreateSuspended参数?)

然而,当你暂停/恢复正在运行的线程时会出现真正的麻烦。主要是因为引用了开放资源,例如COM对象。 (例如,如果你有一个ADO连接对象处于活动状态,并且正在运行一个查询...暂停该线程并尝试稍后恢复它并不是很理想...显然并不总是能够很好地为你做好准备该场景中的数据库连接。)

如果你对你的外部引用小心,那么暂停/恢复正在运行的线程会变得更加安全,除了可能出现的竞争条件......但这些都是许多其他问题的答案......

答案 2 :(得分:1)

是的,对于没有Start程序的旧版Delphi版本,这是正确的方法。

答案 3 :(得分:1)

Delphi 2010和更新版本中不推荐使用Resume和Suspend。似乎它基本上不鼓励使用它们进行线程同步。它们并不意味着它。

无论如何,如果您只想恢复创建的线程,那么在旧版本中调用Resume是安全的。

如果您需要在Delphi 2007和Delphi XE中使用相同的源代码,那么您可以使用条件编译来避免在XE中发出警告。

另外,请看一下与您的问题相关的问题:

TThread.resume is deprecated in Delphi-2010 what should be used in place?

答案 4 :(得分:0)

你永远不应该在tthread上调用suspend这样做是不安全的,并且只能用来启动一个创建被挂起的线程。

在Delphi 2010中,引入了暂停和恢复折旧和方法开始以加强这一点。

有关更完整的说明,请参阅Codegears论坛上的thread