【问题标题】:FreeLibrary freeze when using dbExpress (TSQLConnection)使用 dbExpress (TSQLConnection) 时 FreeLibrary 冻结
【发布时间】:2015-11-12 16:54:47
【问题描述】:

我目前正在开发一些简单的自动更新应用程序。最重要的特点是可以自我更新。这就是为什么我计划将大部分逻辑放在外部 DLL 中。在我的 DLL 长大一点后,我开始在主应用程序中调用 FreeLibrary 时遇到问题。在 dll 调试期间,我发现了导致该错误的函数:

function TpmDSServerUpdateDownloader.DownloadUpdates: Boolean;
var
  LSQLConnection: TSQLConnection;
  LSQLServerMethod: TSqlServerMethod;
  LUpdatePackageLink: string;
begin
  try
    {$IFDEF DEBUG}
    Sleep(10000);
    {$ENDIF}
    // Getting update package link
    FUpdateServerIP := '127.0.0.1';
    FUpdateServerPort := 8080;
    LSQLConnection := TSQLConnection.Create(nil);
    LSQLServerMethod:= TSQLServerMethod.Create(nil);
    LSQLConnection.DriverName :='DataSnap';
    LSQLConnection.LoginPrompt := False;
    LSQLConnection.Params.Add('CommunicationProtocol=HTTP');
    LSQLConnection.Params.Add('Hostname=' + FUpdateServerIP);
    LSQLConnection.Params.Add('Port=' + IntToStr(FUpdateServerPort));
    LSQLConnection.Params.Add('ConnectTimeout=' + IntToStr(10000));
    LSQLConnection.Connected := True;
    LSQLServerMethod.SQLConnection:= LSQLConnection;
    LSQLServerMethod.ServerMethodName:= 'TServerMethods1.GetUpdatePackageLink';
    LSQLServerMethod.Params[0].AsInteger := 1;
    LSQLServerMethod.ExecuteMethod;
    LUpdatePackageLink := LSQLServerMethod.Params[1].AsString;
    // Downloading update package with LUpdatePackage link
  finally
    LSQLConnection.Connected := False;
    LSQLServerMethod.Free;
    FreeAndNil(LSQLConnection);
  end;
end;

当我使用该函数中的 dbExpress 组件时出现问题。我想知道释放 TSQLConnection/TSQLServerMethod 是否会留下一些工作的 dbExpress 线程/对象,就像 IBObjects 中的 SQLMonitor 一样。也许你有一些想法如何解决这个问题?非常感谢您的帮助。

问候 迈克尔

【问题讨论】:

  • 您想知道的事情并不是您需要想知道的事情。您已经在使用调试器,因此请使用它检查是否还有剩余线程。请确认这是一个问题之前询问如何解决它。
  • 感谢您的有用建议。我需要暂时冻结该项目,但现在我正在再次处理它。我对其进行了调试,发现一个线程无法正确终止并阻塞了其他线程。它位于 Data.DBXCommon 单元的 TDBXScheduler 中。在由使用 DLL 的主程序执行的单元完成期间,该程序在该单元的第 17593 行挂起。

标签: delphi dll dbexpress


【解决方案1】:

这是一个 Delphi BUG。

但是有一个解决方案:

无法从 DLL 卸载中调用 Microsoft 关闭线程,因此 FreeLibrary 在 Data.DBXCommon 的初始化部分中创建的 TDBXScheduler 的 TThread.WaitFor proc 中的 WaitForMultipleObject 无限循环中冻结,并将在 Data.DBXCommon 的初始化部分中自动关闭该单元的完成部分。这会导致错误。所以我们必须早点关闭那个线程。

解决方案是你需要在 FreeLibrary 之前导出新过程并调用它:

   uses 
       Data.DBXCommon
    .....
    procedure FinishDLLWork; stdcall; export;
    begin
      TDBXScheduler.Instance.Free;
    end;

并在 FreeLibrary 之前调用它; TDBXScheduler on freeining TDBXScheduler.Instance 将自动将其设置为 Nil,因此此调用很好(检查 TDBXScheduler.Destroy;

很遗憾,它无法在 DLL_THREAD_DETACHDLL_PROCESS_DETACH 中调用 - 为时已晚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2016-02-29
    • 2016-09-02
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多