DataSnap i zwracanie wartości przez funkcję.

DataSnap i zwracanie wartości przez funkcję.
RD
  • Rejestracja:około 12 lat
  • Ostatnio:12 miesięcy
  • Postów:212
0

Napotkałem się na pewien problem. Prosta aplikacja klient-serwer. Poniżej przedstawiam kod:

KOD SERWERA

Kopiuj
{ Zwraca liste użytkowników }
function TServerMethods.GetListUsers: TStringList;
var
  X: Integer;
  MyData: TMyQuery;
begin
  Result := TStringList.Create;
  MyData := TMyQuery.Create(nil);
  try
    MyData.Connection := FServer.MyConnection;
    MyData.SQL.Text := ('SELECT ' + raf_login + ' FROM ' + Key_RafloUser);
    MyData.Active := True;
    MyData.First;
    while not MyData.Eof do
    begin
      Result.Add(MyData.FieldByName(raf_login).AsString);
      MyData.Next;
    end;
  finally
    MyData.Free;
  end;
end;

KOD KLIENTA

Kopiuj
procedure TForm4.Button1Click(Sender: TObject);
var
  Temp: TServerMethodsClient;
begin
  if not DataSnapConnection.Connected then
    DataSnapConnection.Open;
  Temp := TServerMethodsClient.Create(DataSnapConnection.DBXConnection);
  try
    ComboBox1.Items := Temp.GetListUsers;
  finally
    Temp.Free;
    DataSnapConnection.Close;
  end;
end;

Opis problemu:

Klient łączy się z serwerem i otrzymuje listę użytkowników. Jednakże po kilku wywołaniach procedury klienta dostaję AV lub błąd przy zamykaniu aplikacji klienta "Runtime error 216 at 00409EB8".

Natomiast aplikacja serwera zamyka się prawidłowo a FastMM4 nie wykrywa żadnych wycieków.

Próbowałem przerobić tak procedurę aby zwracać wartość przez referencję tzn.

Kopiuj
procedure TServerMethods.GetListUsers(var ListUser:TStringList);

Jednakże to generowało mi jeszcze większe błędy.

Co robię źle, że dostaje AV?

RD
  • Rejestracja:około 12 lat
  • Ostatnio:12 miesięcy
  • Postów:212
0

Jeżeli zwracam dane poprzez TDataSet zamiast TStringList to wszystko działa poprawnie używam komponentu TClientDataSet. Czy czasami nie jest tak że złożone dane takie jak np tablice serwer musi przesyłać po przez TClientDataSet? Zastanawiam się jeszcze w jaki sposób przesyłać całe pliki ...

Kod Serwera

Kopiuj
{ Zwraca liste użytkowników }
function TServerMethods.GetListUsers: TDataSet;
var
  MyData: TMyQuery;
  ClientDataSet1 : TClientDataSet;
begin
  ClientDataSet1 := TClientDataSet.Create(nil);
  MyData := TMyQuery.Create(nil);
  ClientDataSet1.Close;
  ClientDataSet1.FieldDefs.Clear;
  ClientDataSet1.FieldDefs.Add('field1',ftString,20);
  ClientDataSet1.CreateDataSet;
  try
    MyData.Connection := FServer.MyConnection;
    MyData.SQL.Text := ('SELECT ' + raf_login + ' FROM ' + Key_RafloUser);
    MyData.Active := True;
    MyData.First;
    while not MyData.Eof do
    begin
      ClientDataSet1.AppendRecord([MyData.FieldByName(raf_login).AsString]);
      MyData.Next;
    end;
    result := ClientDataSet1;
  finally
    //ClientDataSet1.Free;
    MyData.Free;
  end;
end;

Kod Klienta

Kopiuj
procedure TForm4.Button1Click(Sender: TObject);
var
  link: TServerMethodsClient;
  DS: TdataSet;
  X : Integer;
begin
  if not DataSnapConnection.Connected then
    DataSnapConnection.Open;

  Link := TServerMethodsClient.Create(DataSnapConnection.DBXConnection);
  try
    DS := Link.GetListUsers;
    DS.First;
    Combobox1.Clear;
    while not DS.Eof do begin
      combobox1.Items.Add(DS.FieldByName('field1').AsString);
      DS.Next;
    end;
  finally
    Link.Free;
    DataSnapConnection.Close;
  end;
end;

WAŻNE Dlaczego NIE MA wycieków w serwerze skoro tworze dynamicznie obiekt

Kopiuj
ClientDataSet1 := TClientDataSet.Create(nil);

i go nie zwalniam? Jeśli go zwolnię w bloku finally to funkcja przestaje działać. Czy może mi to ktoś wytłumaczyć?

edytowany 2x, ostatnio: Rafał D
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:3 minuty
0

być może w momencie zamknięcia połączenia przez klienta serwer automatycznie zwalnia dataset będący rezultatem funkcji . tego nie wiem ale tak można by się domyślać na podstawie Twoich obserwacji.
w moich aplikacjach korzystam z Tclientdataset'ów zdefiniowanych w klasie (mam na myśli tylko te, które zwracają rezultaty przez datasnapa) , nigdy nie tworzę ich dynamicznie więc zamknięcie połączenia zwalnia cały zdalny moduł danych łącznie z datasetami

edytowany 2x, ostatnio: grzegorz_so

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.