Dlaczego nie wykonuję mi się procedura Destroy w TDataSnap?
unit RClient;
interface
uses
Winapi.Windows, System.SysUtils, System.Classes, Data.DB, Data.SqlExpr, Metody, Dialogs;
type
TDataSnap = class(TTHread)
private
hEvent: THandle;
vResult: string;
linker: TServerMethods1Client;
SQLConnection: TSQLConnection;
public
property Result: string read vResult;
property SQL: TSQLConnection read SQLConnection write SQLConnection;
constructor Create(var hDataSnap: THandle);
destructor Destroy;
procedure Awake;
protected
procedure Execute; override;
end;
TTimeOut = procedure(Sender: TObject; var VisibleException: boolean) of object;
type
TRafloClient = class(TComponent)
private
hDataSnap : THandle;
fTimeOut: TTimeOut;
SQL: TDataSnap;
fTime: Integer;
fAdress: string;
fPort: string;
fUserName: string;
fPassword: string;
procedure CreateConnection(var SQL: TDataSnap);
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetTest: String;
procedure Connect;
procedure Disconnect;
published
property Adress: string read fAdress write fAdress;
property Port: string read fPort write fPort;
property UserName: string read fUserName write fUserName;
property Password: string read fPassword write fPassword;
property TimeOut: Integer read fTime write fTime default 10000;
property OnTimeOut: TTimeOut read fTimeOut write fTimeOut;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Raflo Component', [TRafloClient]);
end;
constructor TDataSnap.Create(var hDataSnap: THandle);
begin
inherited Create(False);
hEvent := CreateEvent(nil, False, False, nil);
if hEvent = 0 then
raise Exception.Create('Unable to create hEvent in TDataSnap');
hDataSnap := Handle;
FreeOnTerminate := True;
SQLConnection := TSQLConnection.Create(nil);
SQLConnection.DriverName := 'DataSnap';
SQLConnection.LoginPrompt := False;
SQLConnection.Params.Clear;
SQLConnection.Params.Add('DriverUnit=Data.DBXDataSnap');
SQLConnection.Params.Add('CommunicationProtocol=tcp/ip');
SQLConnection.Params.Add('DatasnapContext=datasnap/');
SQLConnection.Params.Add
('DriverAssemblyLoader=Borland.Data.TDBXClientDriverLoader,Borland.Data.DbxClientDriver,Version=19.0.0.0,Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b');
SQLConnection.Params.Add('DriverName=DataSnap');
SQLConnection.Params.Add('HostName=localhost');
SQLConnection.Params.Add('port=211');
SQLConnection.Params.Add('DSAuthenticationUser=');
SQLConnection.Params.Add('DSAuthenticationPassword=');
end;
procedure TDataSnap.Awake;
begin
PulseEvent(hEvent);
end;
destructor TDataSnap.Destroy;
begin
try
SQLConnection.Close;
finally
SQLConnection.Free;
end;
CloseHandle(hEvent);
inherited Destroy;
end;
procedure TDataSnap.Execute;
begin
while not Terminated do
begin
WaitForSingleObject(hEvent, INFINITE);
if Terminated then
Exit;
vResult := 'Wynik';
end;
end;
constructor TRafloClient.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
CreateConnection(SQL);
fTime := 10000;
end;
destructor TRafloClient.Destroy;
var
lpCreationTime: _FileTime;
lpExitTime: _FileTime;
lpKarnelTime: _FileTime;
lpUserTime: _FileTime;
begin
{ Sprawdź czy wątek istnieje / jest uruchomiony }
if GetThreadTimes(hDataSnap, lpCreationTime, lpExitTime, lpKarnelTime, lpUserTime) then
begin
SQL.Terminate;
SQL.Awake;
{ Jeśli czas na zamkniecie wątku minął zabij go gwałtownie }
If WaitForSingleObject(hDataSnap, 5000) = WAIT_TIMEOUT then
TerminateThread(hDataSnap, 0);
end;
inherited Destroy;
end;
procedure TRafloClient.CreateConnection(var SQL: TDataSnap);
begin
SQL := TDataSnap.Create(hDataSnap);
SQL.SQL.Params.Values['HostName'] := fAdress;
SQL.SQL.Params.Values['Port'] := fPort;
SQL.SQL.Params.Values['DSAuthenticationUser'] := fUserName;
SQL.SQL.Params.Values['DSAuthenticationPassword'] := fPassword;
end;
function TRafloClient.GetTest;
var
X: Integer;
CzyRaise: boolean;
begin
CzyRaise := True;
SQL.Awake;
X := 0;
Repeat
inc(X);
if SQL.Result <> '' then
break;
sleep(100);
Until X >= fTime div 100;
if X >= fTime div 100 then
if assigned(OnTimeOut) then
OnTimeOut(Self, CzyRaise);
Result := SQL.Result;
end;
end.