在DLL中使用TTASK时,Delphi Freelibrary冻结



这是我在dll中的代码:

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

在主机应用程序中调用此方法后,请致电FreeLibrary冻结主机应用程序。调试后,我发现该程序在TLightweightEvent.WaitFor中的if TMonitor.Wait(FLock, Timeout) then冻结,但是调试器无法介入TMonitor.Wait。如何解决?

报告了此问题(RSP-13742 ITASK问题,ifuture dll中的ifuture)。

它是按预期的"工作"封闭的:

要防止使用iTask或ifuture从DLL中进行此故障,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.

另一种方法是在加载库时创建ThreadPool,并添加一个释放过程,您在调用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.

最新更新