在DLL中使用TTask时 Delphi FreeLibrary冻结

o75abkj4  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(172)

下面是我的DLL代码:

procedure TTaskTest;
begin
  TTask.Run(
    procedure
    begin
      Sleep(300);
    end);
end;
exports TTaskTest;

在宿主app中调用此方法后,再调用FreeLibrary会冻结宿主app,调试后发现程序在TLightweightEvent.WaitFor中的if TMonitor.Wait(FLock, Timeout) then处冻结,但调试器无法单步执行到TMonitor.Wait,如何解决?

cetgtptt

cetgtptt1#

已报告此问题(RSP-13742 Problem with ITask, IFuture inside DLL)。
它以“按预期工作”结束,并附有一条备注:

  • 若要防止从DLL使用ITask或IFuture时发生此故障,DLL需要使用自己的TThreadPool示例来代替TThreadPool的默认示例。*

下面是Embarcadero的一个示例,如何处理它:

library TestLib;

uses
  System.SysUtils,
  System.Classes,
  System.Threading;

{$R *.res}

VAR
  tpool: TThreadPool;

procedure TestDelay;
begin
  tpool := TThreadPool.Create;
  try
    TTask.Run(
      procedure begin
        Sleep(300);
      end,
      tpool
    );
  finally
    FreeAndNil(tpool);
  end;
end;

exports
  TestDelay;

begin

end.

另一种方法是在加载库时创建线程池,并添加一个释放过程,在调用FreeLibrary之前调用该过程。

// In dll 
procedure TestDelay;
begin
  TTask.Run(
    procedure begin
      Sleep(300);
    end,
    tpool
  );
end;

procedure ReleaseThreadPool;
begin
  FreeAndNil(tpool);
end;

exports
  TestDelay,ReleaseThreadPool;

begin
  tpool := TThreadPool.Create;
end.

相关问题