Search code examples
delphitclientdataset

How to auto delete clientdataset records that have not been updated


I have a clientdataset in RAM no database, that maintains a list of active nodes in a network.
Nodes continuously report back confirming they are alive, thus keeping the dataset updated.
The dataset is displayed in a dbgrid.

When a node stops reporting status it is deleted from the database after a few seconds inactivity.
I do this by updating a timeout field when a field is updated.
Every second I iterate through the dataset deleting outdated records.

This works, but the grid sometimes flicker when OnDrawColumnCell refreshes a single line grid to customize the column colors. I call DisableControls/EnableControls, but there seems to be a small delay until OnDrawCell redraws the grid causing the flicker.

If I disable the iteration to delete the outdated records the flicker stops.
Is there a better way to do this?


Solution

  • A way to minimise the flicker in your grid is to use a 'trick' which makes use of a special feature of ClientDataSets, namely that you can copy data between them by assigning their Data properties, as in

    cdsDestination.Data := cdsSource.Data;
    

    So what you can do is to have two CDSs, one which you use for display purposes only, and the other which processes your network nodes. This means that changes to the copy CDS are kept to the absolute minimum, and you can do pretty much whatever you like with your source CDS, and take as long as you like about it (as long, of course, as you can get it done before the next destination CDS update). Something like this:

    const
      NodeCount = 1000;
    
    procedure TForm1.DoDataUpdate;
    begin
      //  do something to CDS1's data here
      cdsCopy.Data := CDS1.Data;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i : Integer;
    begin
      CDS1.CreateDataSet;
      for i := 1 to NodeCount do
        CDS1.InsertRecord([i, Now]);
      CDS1.First;
      DBGrid1.DataSource := DataSource1;
      DataSource1.DataSet := cdsCopy;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      DoDataUpdate;
    end;