首页 > 解决方案 > Delphi:TTask 似乎只有第一次慢

问题描述

在按钮单击上,我创建了 3 个任务,每个任务都带有空过程,并将与方法调用的时间差和任务列表完成的时间差写入控制台:

procedure TWinTest.BtnThreadTestClick(Sender: TObject);
var
  aTasks: array of ITask;
  aStart: Cardinal;
begin
  aStart := GetTickCount;

  Setlength(aTasks, 3);

  aTasks[0] := TTask.Create(procedure() begin

  end);
  aTasks[0].Start;

  aTasks[1] := TTask.Create(procedure() begin

  end);
  aTasks[1].Start;

  aTasks[2] := TTask.Create(procedure() begin

  end);
  aTasks[2].Start;

  TTask.WaitForAll(aTasks);


  Writeln( GetTickCount - aStart, 'ms');
end;

第一次调用需要 31 毫秒,后续调用需要 0 毫秒。

在此处输入图像描述

为什么第一个调用比连续调用慢?也许delphi缓存线程并在后续调用中重用它?

标签: delphi

解决方案


是的,默认情况下,任务线程被缓存(在线程池中)。这是记录在案的行为:

教程:使用并行编程库中的任务

 本教程展示了如何使用并行编程库 (PPL) 中的 任务来实现应用程序 。任务 是队列中的工作单元,在 CPU 时间可用时启动。 任务可以并行运行操作。有一个主线程管理这个队列并从 线程池中分配线程来完成任务的工作。此 线程池具有多个线程,具体取决于可用 CPU 的数量。

您可以通过创建TThreadPool对象并将其传递给TTask构造函数来自定义池的行为:

如果需要,还可以为 Create 提供一个 TThreadPool 的参数,  TTask的实例 可以从中提取 它需要的线程资源。如果不指定 TThreadPool的实例,则根据平台的 CPU 和线程功能从默认值中提取资源。


推荐阅读