35

在我的多线程应用程序中

我使用TThread.suspendTThread.resume

自从将我的应用程序移至 Delphi 2010 以来,我收到以下交战消息

[DCC 警告] xxx.pas(277): W1000 符号“恢复”已弃用

如果不推荐使用 Resume,应该使用什么?

编辑1:

我使用Resume命令来启动线程 - 因为它是在我终止线程之前将“CreateSuspended”设置为 True 并暂停创建的。

编辑2:

这是delphi 2010手册的链接

4

8 回答 8

29

Charles 如果你读过 TThread 类的代码,你找到答案了吗?

   TThread = class  
   private type  

..
..
..   
   public  
     constructor Create(CreateSuspended: Boolean);  
     destructor Destroy; override;  
     procedure AfterConstruction; override;  
     // This function is not intended to be used for thread synchronization.  
     procedure Resume; deprecated;  
     // Use Start after creating a suspended thread.  
     procedure Start;  
     // This function is not intended to be used for thread synchronization.  
     procedure Suspend; deprecated;  
     procedure Terminate;  

请参阅此链接RAD Studio 2010:社区脉搏:后天。(第2部分)

编辑:

如果需要同步线程,可以使用基于 TMutex、TEvent 和临界区的方案。

再见。

于 2009-09-13T18:02:29.290 回答
13

使用 TThread.Start 而不是 .Resume

--EDIT-- Start 当然只能与Delphi 2010(以及以后,大概)一起使用来启动一个创建为挂起的线程(您之前会使用Resume)。

不推荐使用 Resume/Suspend(或相应的 WinAPI 函数)进行线程同步。请参阅此处的讨论(查看 Barry Kelly 的评论)。

于 2009-09-13T17:49:46.537 回答
7

SuspendResume可能(或曾经)在TThread类中被破坏(如果您查看源代码,您会看到 Suspend 方法直接且无条件地将布尔值设置为指示线程挂起状态,而不是更稳健地从线程句柄上的执行计数。具有讽刺意味的是,Resume方法确实使用这个更强大的指示器来更新挂起状态 Boolean)。

这可能是它们被弃用的原因。这也是为什么我实现了自己的类来封装具有更强大的挂起和恢复机制的 Windows 线程,以及在线程完成后重新启动线程的能力。

我不确定为什么他们的弃用据说与同步有关。挂起和恢复线程不一定与同步有关,尽管我可以看到它可能是怎样的。有趣的是,.NET 框架 Thread 类中的等效方法同样被标记为已过时。线程挂起/恢复的 Windows API 文档中出现了与同步相同的注释。

如果使用不推荐使用的方法让您感到紧张并且您仍然希望暂停/恢复,您始终可以使用 Windows API通过引用它的句柄来暂停和恢复线程

于 2009-09-13T20:55:18.457 回答
5

以防万一您只想摆脱编译器提示

(1) 在启动线程时摆脱编译器提示...

代替

MyThread := TMyThread.Create(True);
MyThread.Resume;

MyThread := TMyThread.Create(True);
MyThread.Start;

(2) 在停止线程时摆脱编译器提示...

代替

MyThread.Suspend;
MyThread.Terminate;

MyThread.Terminate;

没什么大不了的。谨防企图混淆

于 2013-07-29T05:33:23.427 回答
4

线程行为控制代码应该位于一个线程过程中。使用适当的同步对象和相应的 API 调用来暂停/恢复线程执行。从外面做是一种危险的做法。所以决定贬低它。

于 2009-09-13T18:55:27.293 回答
3

您应该按如下方式创建线程:

constructor TSignalThread.Create;
begin
 // create event handle first!
  FEventHandle := CreateEvent(
          {security}      nil,
          {bManualReset}  true,
          {bInitialState} false,
          {name}          nil);
  FWaitTime := 10;
  inherited Create({CreateSuspended}false);
end;

这样就不需要调用 Start 了。

请参阅http://www.gerixsoft.com/blog/delphi/creating-threads了解为什么此代码有效。

于 2010-07-03T15:55:47.877 回答
3

利用

Suspended := False; // Resume;

或者

Start;
于 2013-09-24T06:21:44.230 回答
2

@mghie(我知道有点晚了)

以 madexcept 等为例。如果您的应用程序崩溃并且正在向用户显示错误报告,这意味着该对话框正在等待用户输入。如果发生崩溃是线程操作的结果(不一定是线程崩溃),如果您不暂停线程,则屏幕将充满错误报告对话框。

示例 2:日志记录。出于任何特殊原因,我至少需要记录一些线程的执行状态。这包括当前的堆栈跟踪。现在,正如您(应该)知道的那样,您不能在线程运行时执行此操作,因为在您收集有关它的信息期间,线程一直在做一些事情,所以当您完成收集时,收集的信息将不一致。因此,您需要暂停线程。

我可以继续讨论线程管理的实际示例。诚然,这些不是您在日常编程中所做的事情,但至少我确信你们中的许多人都在使用第一个示例,即使您不了解它的内部结构。调试器?再次,您使用它们。但实际上,在所有这些情况下,都没有使用 TThread,因为工作是在线程句柄上完成的。因此,确实很难找到一个有效的 TThread 挂起用法示例。但总的来说,线程是另一回事。

于 2011-03-01T08:32:42.520 回答