即使事件被多次触发,c#如何只执行一次逻辑?

问题描述 投票:0回答:1

我正在做一个项目并遇到以下问题。我有一个主类,它读取 xml 并将其显示在 UI 中。对于每个数据点,它都会实例化另一个类的对象,该类保存所有信息。数据保存在一个列表中,该列表具有嵌套列表直至数据点。它就像一个树结构。这是保存信息的子类:

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


}

当选中 UI 中的复选框时,会触发一个事件来检查所有底层数据点(OnPropertyChanged 事件)。

我还有一个计数器,可以计算并显示检查的数据点的数量。问题就从这里开始了。我触发事件 OnRestoreVarChanged 来告诉主类发生了一些变化,它应该重新计算变量的数量并更新 UI。但由于我还检查每个子数据点,它经常触发。 如果我有大约一百万个数据点并检查最上面的数据点,它会将所有变量重新计数一百万次,这并不是很好的性能虎钳(显然)。

这是我的事件,它监听每个实例的事件:

    private void SomeCheckboxChaneged(object sender, EventArgs e)
    {
        UI_Counter = Count(ListofDatapoints); //returns the amount of checked datapoints
        NotifyPropertyChanged("UI_Counter");
    }
        

这原则上是可行的,但正如我所说,这是性能非常糟糕的虎钳。 我考虑过使用一个计时器,每次触发事件时都会重新启动,并在最后一个事件结束后启动计数器一次。但我讨厌在 C# 中使用计时器。你还有其他选择吗?还是我对计时器的恐惧有点过大?

c# events timer
1个回答
0
投票

所以我用计时器尝试了一下,效果非常完美。感谢@Fildor 的建议。 每次选中复选框和子复选框时都会触发 SomeCheckboxChanged 事件。它每次都会重新启动计时器,并且仅当计时器到时才会执行计数逻辑并更新 UI。

    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();
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.