誰かが知りたい場合に備えて、ソリューションは実装がかなり簡単でした。これで、クライアント アプリが DataSnap サーバーが要求を処理するのを待っている間はいつでも増加する、動作中の経過時間クロック [0:00] ができました。本質的に、これが私たちがしたことです。(解決策を共有してくれた人たちに特に感謝します。私の考えを導くのに役立ちました。 )
サーバーによって生成されたクラス (ProxyMethods) は、VCL スレッドで作成する必要がありますが、別のスレッドで実行する必要があります。これを行うために、ProxyMethods ラッパー クラスと ProxyMehtods スレッド クラスを作成しました (これらはすべてこの例のために考案されたものですが、それでもフローを示しています)。
ProxyMethods.pas
...
type
TServerMethodsClient = class(TDSAdminClient)
private
FGetDataCommand: TDBXCommand;
public
...
function GetData(Param1: string; Param2: string): string;
...
end;
ProxyWrapper.pas
...
type
TServerMethodsWrapper = class(TServerMethodsClient)
private
FParam1: string;
FParam2: string;
FResult: string;
public
constructor Create; reintroduce;
procedure GetData(Param1: string; Param2: string);
procedure _Execute;
function GetResult: string;
end;
TServerMethodsThread = class(TThread)
private
FServerMethodsWrapper: TServerMethodsWrapper;
protected
procedure Execute; override;
public
constructor Create(ServerMethodsWrapper: TServerMethodsWrapper);
end;
implementation
constructor TServerMethodsWrapper.Create;
begin
inherited Create(ASQLServerConnection.DBXConnection, True);
end;
procedure TServerMethodsWrapper.GetData(Param1: string; Param2: string);
begin
FParam1 := Param1;
FParam2 := Param2;
end;
procedure TServerMethodsWrapper._Execute;
begin
FResult := inherited GetData(FParam1, FParam2);
end;
function TServerMethodsWrapper.GetResult: string;
begin
Result := FResult;
end;
constructor TServerMethodsThread.Create(ServerMethodsWrapper: TServerMethodsWrapper);
begin
FServerMethodsWrapper := ServerMethodsWrapper;
FreeOnTerminate := False;
inherited Create(False);
end;
procedure TServerMethodsThread.Execute;
begin
FServerMethodsWrapper._Execute;
end;
ProxyMethod の実行を 2 つのステップに分割したことがわかります。最初のステップは、パラメーターの値をプライベート変数に格納することです。これにより、_Execute()
メソッドは実際の ProxyMethods メソッドを実行するときに必要な情報をすべて取得でき、その結果はFResult
後で取得できるように格納されます。
ProxyMethods クラスに複数の関数がある場合FProcID
、プライベート変数を設定するためにメソッドが呼び出されたときに、各メソッドを簡単にラップして内部変数 ( など) を設定します。このようにして、_Execute()
メソッドはFProcID
どの ProxyMethod を実行するかを知るために使用できます...
スレッドが自分自身を解放しない理由を疑問に思うかもしれません。その理由は、スレッドが独自のクリーンアップを行ったときに、 「スレッド エラー: ハンドルが無効です (6) 」というエラーを除去できなかったためです。
ラッパー クラスを呼び出すコードは次のようになります。
var
smw: TServerMethodsWrapper;
val: string;
begin
...
smw := TServerMethodsWrapper.Create;
try
smw.GetData('value1', 'value2');
// start timer here
with TServerMethodsThread.Create(smw) do
begin
WaitFor;
Free;
end;
// stop / reset timer here
val := smw.GetResult;
finally
FreeAndNil(smw);
end;
...
end;
WaitFor
ProxyMethods スレッドが完了するまでコードの実行を中断します。smw.GetResult
スレッドの実行が完了するまで必要な値を返さないため、これが必要です。プロキシ実行スレッドがビジー状態のときに経過時間クロック [0:00] をインクリメントするための鍵は、 を使用しTJvThreadTimer
て UI を更新することです。ProxyMethodTTimer
が別のスレッドで実行されていても、VCL スレッドが を待機しているWaitFor
ため、は機能せず、 が完了TTimer.OnTimer()
するまで は実行されませんWaitFor
。
参考までに、TJvTheadTimer.OnTimer()
コードは次のようになり、アプリケーションのステータス バーが更新されます。
var
sec: Integer;
begin
sec := DateUtils.SecondsBetween(Now, FBusyStart);
StatusBar1.Panels[0].Text := Format('%d:%.2d', [sec div 60, sec mod 60]);
StatusBar1.Repaint;
end;