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?
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;