在DLL中使用TTask时,Delphi FreeLibrary会冻结

时间:2016-12-15 08:15:56

标签: delphi dll

这是我在DLL中的代码:

<Grid.Resources>
      <DataTemplate DataType="{x:Type local:Class1}">
             <-- Template for class1 -->
       </DataTemplate>
       <DataTemplate DataType="{x:Type local:Class2}">
             <-- Template for class2 -->
       </DataTemplate>
</Grid.Resources>

在主机应用中调用此方法后,调用procedure TTaskTest; begin TTask.Run( procedure begin Sleep(300); end); end; exports TTaskTest; 将冻结主机应用。 调试后,我发现该程序在FreeLibrary的{​​{1}}冻结,但调试器无法进入if TMonitor.Wait(FLock, Timeout) then。 怎么解决?

1 个答案:

答案 0 :(得分:3)

报告了此问题(RSP-13742 Problem with ITask, IFuture inside DLL)。

已关闭&#34;按预期工作&#34;一句话:

  

为了防止在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.