I am working on a project and had the following problem. I have a main class which reads an xml and displays it in the UI. For every datapoint it instantiates an object of another class which the holds all the information. The Data is held in a list which has nested lists down to the datapoints. It is like a tree structure.This is the subclass which holds the information:
public class DatapointInstance : INotifyPropertyChanged
{
private bool restoreVar;
private List<DatapointInstance> subVariables;
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler RestoreVarChanged;
public string Name{ get; set; }
public string Value { get; set; }
//some more properties
public bool RestoreVar //Checkbox
{
get { return restoreVar; }
set { if (restoreVar != value)
{ restoreVar = value;
OnPropertyChanged(nameof(RestoreVar));
OnRestoreVarChanged(); } }
}
public List<DatapointInstance> SubVariables //This one is to make the tree structure possible
{
get { return subVariables; }
set { if (subVariables != value) { subVariables = value; OnPropertyChanged(nameof(SubVariables)); } }
}
protected virtual void OnRestoreVarChanged()
{
RestoreVarChanged?.Invoke(this, EventArgs.Empty);
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
foreach (var item in subVariables)
{
item.RestoreVar = RestoreVar;
}
}
}
When the checkbox in the UI is checked an event is fired to check all underlying Datapoints aswell (OnPropertyChanged Event).
I also have a counter which counts and displays the amount of checked datapoints. And here the problem begins. I fire the Event OnRestoreVarChanged to tell the main class something has changed and it should recount the amount of variables and update the UI. But due to the fact that I also check every sub datapoint it fires very often. If I have like one million datapoints and check the topmost it recounts all variables a million times and that isnt very good performance vise (obviously).
This is my event which listens to the Event of every instance:
private void SomeCheckboxChaneged(object sender, EventArgs e)
{
UI_Counter = Count(ListofDatapoints); //returns the amount of checked datapoints
NotifyPropertyChanged("UI_Counter");
}
This works in principle but as I said it is very bad perfomance vise. I thought about using a Timer which restarts every time the event is fired and after the last event it elapses and starts the counter ONE time. But I hate working with timers in C#. Do you have another option or is my fear of timers a bit to big?
So I tried it with a timer and it works just perfect. Thanks for the advice @Fildor. The SomeCheckboxChanged Event gets fired every time a checkbox and a sub checkbox is checked. It restarts the timer every time and only when the timer elapses the count-logic gets executed and the UI updates.
private System.Timers.Timer timer;
private bool isTimerStarted = false;
private void SomeCheckboxChaneged(object sender, EventArgs e)
{
// Check if the timer has already been started
if (!isTimerStarted)
{
// If not, create and start the timer
timer = new System.Timers.Timer();
timer.Interval = 50;
timer.Elapsed += OnTimerElapsed;
timer.Start();
isTimerStarted = true;
}
else
{
// If the timer is already started, reset it
timer.Stop();
timer.Start();
}
private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
UI_Counter = Count(ListofDatapoints); //returns the amount of checked datapoints
NotifyPropertyChanged("UI_Counter");
// Reset the flag
isTimerStarted = false;
// Stop and dispose the timer
if (timer != null)
{
timer.Stop();
timer.Dispose();
}
}