我目前正在开发一些简单的自动更新程序应用程序。最重要的特征是自我更新的可能性。这就是我计划将大多数逻辑放在外部DLL中的原因。在我的DLL增长了一点后,我开始在主应用程序中遇到FreeLibrary调用问题。在dll调试期间,我发现函数负责该bug:
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一样。也许你有一些想法如何解决?我非常感谢你的帮助。
问候 米甲
答案 0 :(得分:0)
这是一个Delphi错误。
但是有解决方案:
以下Microsoft关闭线程无法从DLL卸载中调用,因此FreeLibrary将在Data.DBXCommon的初始化部分中创建的TDBXScheduler的TThread.WaitFor proc中的WaitForMultipleObject inifinite循环上进行冻结,并在其中自动关闭该单元的最终化部分。这会导致错误。因此,我们必须更早关闭该线程。
解决方案是您需要导出新过程并在FreeLibrary之前调用它:
uses
Data.DBXCommon
.....
procedure FinishDLLWork; stdcall; export;
begin
TDBXScheduler.Instance.Free;
end;
并在FreeLibrary之前调用它;
释放TDBXScheduler
时TDBXScheduler.Instance
会自动将其设置为Nil,因此此调用正常(请检查TDBXScheduler.Destroy;
)
很遗憾,它无法在DLL_THREAD_DETACH
或DLL_PROCESS_DETACH
中调用-为时已晚。