You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 12(已打补丁)TParallel.For循环结束后CPU占用过高求助

Delphi 12 TParallel.For 执行后CPU高占用问题解决办法

问题重现代码

procedure TForm1.Button2Click(Sender: TObject);
var
  lF: TParallel;
begin
     lF := TParallel.Create;
     try

       lF.&For(1, 100000,
         procedure(I: Integer)
         var x: Integer;
             lList: TStringList;
         begin
              lList := TStringList.Create;
              try
                lList.Add(i.ToString);
              finally
                lList.Free;
              end;
         end );

     finally
       FreeAndNIL(lF);
     end;
end;

问题现象

  • Delphi 11.3中,仅TParallel.For执行期间占用CPU,循环结束后CPU占用率恢复至0
  • Delphi 12(已打补丁)中,循环执行结束后CPU仍保持高占用状态
  • 调整TThreadPool.Default.SetMaxWorkerThreads参数后问题未解决

可行解决办法

1. 改用TParallel静态方法(推荐)

TParallel的设计初衷是使用其静态方法而非手动实例化对象,手动创建TParallel实例可能导致线程池资源无法正确回收。修改代码如下:

procedure TForm1.Button2Click(Sender: TObject);
begin
  TParallel.&For(1, 100000,
    procedure(I: Integer)
    var 
      lList: TStringList;
    begin
      lList := TStringList.Create;
      try
        lList.Add(I.ToString);
      finally
        lList.Free;
      end;
    end);
end;

2. 配置线程池空闲超时

如果必须保留实例化方式,可在循环结束后显式设置线程池的空闲线程超时,让闲置线程自动销毁:

procedure TForm1.Button2Click(Sender: TObject);
var
  lF: TParallel;
begin
  lF := TParallel.Create;
  try
    lF.&For(1, 100000,
      procedure(I: Integer)
      var 
        lList: TStringList;
      begin
        lList := TStringList.Create;
        try
          lList.Add(I.ToString);
        finally
          lList.Free;
        end;
      end);
    
    // 配置线程池参数,让闲置线程自动退出
    TThreadPool.Default.SetMinWorkerThreads(0);
    TThreadPool.Default.SetMaxWorkerThreads(Environment.Process.Affinity.Count);
    TThreadPool.Default.IdleThreadTimeout := 1000; // 闲置1秒后销毁线程
  finally
    FreeAndNIL(lF);
  end;
end;

3. 手动终止线程池(极端场景)

若上述方法无效,可在循环结束后手动终止线程池(注意:此操作会销毁所有线程池线程,可能影响其他依赖线程池的代码):

finally
  FreeAndNIL(lF);
  TThreadPool.Default.Terminate;
end;

问题原因分析

Delphi 12对TParallel和TThreadPool的内部实现做了调整,手动实例化TParallel可能打破了线程池的资源回收逻辑,导致线程池中的工作线程在任务结束后仍保持活跃状态,持续占用CPU资源。而Delphi 11.3的线程池回收机制更激进,闲置线程会快速退出。

内容的提问来源于stack exchange,提问作者Toni Grabmayr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 17:53:11