I have a db application that fetches db record-set asynchronously very similatr to Threaded Delphi ADO Query
Each time the user clicks refresh a new TDBThread
is created to get a record-set.
When that happens I want to discard all previous requests and process only the last one.
So I made a class field called FRequestID
which I increment each time a request is made. I do not attempt to cancel/abort previous requests and I don't keep reference to the threads created.
procedure TForm1.RefreshClick(Sender: TObject);
var
T: TDBThread;
begin
Inc(FRequestID);
T := TDBThread.Create(True); // Suspended
T.FreeOnTerminate := True;
T.RequestID := FRequestID;
T.SQL := 'select * from mytable where ...';
T.OnTerminate := DBThreadTerminate;
T.Resume;
end;
And on terminate I check if the the thread RequestID
is the last FRequestID
, and only then I handle the request.
procedure TForm1.DBThreadTerminate(Sender: TObject);
var
T: TDBThread;
begin
T := TDBThread(Sender);
if FRequestID = T.RequestID then
begin
Memo1.Lines.Add('*** Thread terminated ok ' + IntToStr(T.RequestID));
MainDS.RecordSet := T.RecordSet;
end
else
Memo1.Lines.Add('Thread discarded: ' + IntToStr(T.RequestID ));
end;
My question is this approach correct (and thread safe) and if there is a better way to handle only the last request?
Note: I'm on Delphi 7.