Open TDAMemDataTable Async

Hello,

I’d be grateful if you could provide me with an example on how to open a TDAMemDataTable(Delphi) async. I am trying to make sure that the gui does not freeze while awaiting data from the server. Unless I’m mistaken but I think DA for XCode has methods like DARemoteDataAdapter.beginGetDataTable which I presume accomplish precisely that. Can this be mimicked DA in Delphi? . Pointers on how to achieve this will be greatly appreciated

Regards

Hello,

  1. You can open data tables in a separate thread.
  2. DA provides async services. You can find them in DataAbstract4_Async.pas file.
    But you can’t assign async service with RemoteDataAdapter, so you should control by
    IDataAbstractService_Async methods manually to work with data.
var
  fService: IDataAbstractService_Async;
  fData: Binary;
  aTableList: StringArray;
  aTableRequestInfoArray: TableRequestInfoArray;
begin
  aTableList := StringArray.Create;
  aTableRequestInfoArray := TableRequestInfoArray.Create;
  try
    with aTableRequestInfoArray.Add do
    begin
      IncludeSchema := True;
      MaxRecords := -1;
    end;
    aTableList.Add('CUSTOMER');
    fService := CoDataAbstractService_Async.Create(ClientDataModule.Message,
      ClientDataModule.ClientChannel);
    fService.Invoke_GetData(aTableList, aTableRequestInfoArray);
    
    repeat until fService.AnswerReceived; // wait

    fData := fService.Retrieve_GetData();
    try
      DataStreamer.ReadDataset(fData, DAMemDataTable1, True);
    finally
      FreeAndNil(fData);
    end;
  finally
    FreeAndNil(aTableList);
    FreeAndNil(aTableRequestInfoArray);
  end;
end;
1 Like

Thank you very much for your help. Should I go with option 1. which components must be created in that separate thread. I mean the ones that are not thread-safe.
1.Channel ?
2.Message ?
3.RDA ?

Hello,
Yes, you should put all these components to separate thread. Also you should put datastreamer.

Hello,

are there any plans to implement functions like fillAsync, applyUpdatesAsync into TDARemoteDataAdapter (which seems to be implemented in RemoteDataAdapter for Java)?

For now I think I’ll go with a seperated thread, too but there’s one open point for me:

how can I pass over a Session (created in Main-Thread) to the worker-thread? Is it just as simple as passing by the ClientID to the Channel of the thread? Or should I clone the channel (or all channel, message, rda, datastreamer) of the main thread while creating the thread?

Another option whould be the *Async-Interface, but there’s so much stuff implemented within RDA that all has to be redone in this context and for me this can’t be an option.

Best regards,
Peter

I’ve tried a little bit but the progress of all is not very convincing:

  1. I can just use a ClientID, assign it to any Channel and heist the session (even on a completely different computer!)
  2. There seems to be some race-conditions when doing:
    {PROBLEM:}
    stcpThread  := TROSuperTCPChannel.Create( nil );
    stcpThread.Assign( stcpMain );
    stcpThread.ClientID := stcpMain.ClientID; {Server sometimes not recognize this change}
    ``
    {WORKING:}
    stcpThread  := TROSuperTCPChannel.Create( nil );
    stcpThread.ClientID := stcpMain.ClientID;
    stcpThread.Assign( stcpMain ); {Here the channel already has the ClientID before connecting!}
    I’m not sure why a new ClientID is created anyhow (because I assumed .Assign will just clone this kind of data)
  3. Events: In the moment I disconnect this ‘cloned’ connection I will no longer be able to receive events.

So either I use a seperate thread, keep the comfort of RemoteDataAdapter and run into troubles using events or I use *Async-Interface and I’ll run into lots of problems with M/D, AutoInc, Refresh and so on because of missing Async-RDA-Implementation

Is there any way out?

Best regards,
Peter