Delphi 使用dbExpress时FreeLibrary冻结(TSQLConnection)
我目前正在开发一些简单的自动更新应用程序。最重要的特性是可以自我更新。这就是为什么我计划将大部分逻辑放在外部DLL中。在我的DLL增长了一点之后,我开始在主应用程序中调用FreeLibrary出现问题。在dll调试期间,我发现函数导致了该错误:Delphi 使用dbExpress时FreeLibrary冻结(TSQLConnection),delphi,dll,dbexpress,Delphi,Dll,Dbexpress,我目前正在开发一些简单的自动更新应用程序。最重要的特性是可以自我更新。这就是为什么我计划将大部分逻辑放在外部DLL中。在我的DLL增长了一点之后,我开始在主应用程序中调用FreeLibrary出现问题。在dll调试期间,我发现函数导致了该错误: function TpmDSServerUpdateDownloader.DownloadUpdates: Boolean; var LSQLConnection: TSQLConnection; LSQLServerMethod: TSqlSe
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线程/对象像IBMObjects中的SQLMonitor一样工作。也许你有办法解决这个问题?我将非常感谢你的帮助
问候
Michal这是一个Delphi错误
但是,有一个解决方案:
以下Microsoft closing thread无法从DLL unload调用,因此TDBXScheduler的TThread.WaitFor过程中的WaitForMultipleObject有限循环上的FreeLibrary freez将在Data.DBXCommon的初始化部分创建,并将在该单元的finalization部分自动关闭。这就产生了错误。因此,我们必须更早地关闭该线程
解决方案是您需要导出新过程并在FreeLibrary之前调用它:
uses
Data.DBXCommon
.....
procedure FinishDLLWork; stdcall; export;
begin
TDBXScheduler.Instance.Free;
end;
就在免费图书馆之前;
TDBXScheduler
在释放时TDBXScheduler.Instance
将自动将其设置为Nil,以便此调用正常(检查TDBXScheduler.Destroy;
)
不幸的是,它不能在
DLL\u THREAD\u DETACH
或DLL\u PROCESS\u DETACH
中调用-太晚了。你想知道的事情不是你需要知道的。您已经在使用调试器,请使用它检查是否还有剩余的线程。在询问如何解决之前,请确认这是一个问题。谢谢您的建议。我需要暂时冻结那个项目,但现在我又在做了。我调试了它,发现一个线程不能正确终止,并且阻塞了其他线程。它位于Data.DBXCommon单元中的TDBXScheduler中。在使用DLL的主程序执行单元终结期间,程序挂起在该单元的第17593行。