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
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;
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 ?
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.
I’ve tried a little bit but the progress of all is not very convincing:
I can just use a ClientID, assign it to any Channel and heist the session (even on a completely different computer!)
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)
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