0

我有一个类似于以下的类:

public delegate void FanChangedEventHandler(Fan sender, EventArgs e);

public class Fan: BindableProperty
{   
    #region Blade parameters
    //These Parameters apply to individual blades but are the same for each blade.

    private double length;
    public double Length
    {
        get
        {
            return length;
        }
        set
        {
            length = value;
            NotifyPropertyChanged("Length");
            OnFanChanged(EventArgs.Empty);
        }
    }

    #endregion

    #region Preliminary Fan Outputs
    public double thrust
    {
        get
        {
            return GetThrust();
        }
    }
    private double GetThrust()
    {
        double ThrustSum = 0;
        for(int i = 0; i < Blades.count; i++)
        {
              ThrustSum += Blades[i].Thrust;
        }

        return ThrustSum;
    }
    #endregion

    #region Final Fan Outputs
    public double FinalThrust
    {
        get
        {
            return GetFinalThrust();
        }
    }
    private double GetFinalThrust()
    {
        double TotalWind = 0;
        for(int i = 0; i < Winds.count;i++)
        {
             TotalWind += Winds[i];
        }

        return Thrust + TotalWind;
    }
    #endregion

    private List<Blade> blades;
    public List<Blade> Blades
    {
        get
        {
            return blades;
        }
        set
        {
            blades = value;
            NotifyPropertyChanged("Blades");
        }
    }

    private List<Wind> winds;
    public List<Wind> Winds
    {
        get
        {
            return winds;
        }
        set
        {
            winds = value;
            NotifyPropertyChanged("Winds");
        }
    }

    public event FanChangedEventHandler FanChanged;
    protected virtual void OnFanChanged(EventArgs e)
    {
        try
        {
            UpdateProperties();

            //This seems verbose, but it is important.
            //http://blogs.msdn.com/csharpfaq/archive/2004/03/19/93082.aspx
            FanChangedEventHandler handler = FanChanged;

            if (handler != null)
                handler(this, e);
        }
        catch (Exception ex)
        {
            string error = ex.Message;
        }
    }

    public Fan()
    {
        Length = 21.75;

        Blades = new List<Blade>();
        for (int i = 0; i < 5; i++)
        {
            Blades.Add(new Blade(this));
            Blades[i].BladeChanged += new BladeChangedEventHandler(Blade_Changed);
        }

        Winds = new List<Wind>();
        for (int i = 0; i < 3; i++)
        {
            Winds.Add(new Wind());
            RegisterWind(Winds[i]);
        }
    }

    public void RegisterWind(Wind wind)
    {
        wind.WindChanged += new WindChangedEventHandler(Wind_Changed);
    }

    private void Blade_Changed(Blade sender, EventArgs e)
    {
        UpdateProperties();
    }

    private void Wind_Changed(Wind sender, EventArgs e)
    {
        UpdateProperties();
    }

    private void UpdateProperties()
    {
            NotifyPropertyChanged("Thrust");
            NotifyPropertyChanged("FinalThrust");
    }
}

因此,如果您更改长度参数,它会触发一个事件。此事件通知所有刀片它们应该更新自己,刀片更新自己,然后在它们发生更改时通知,风扇依次更新自己。

我遇到了几个问题,一个是如果我改变Length,Fan会更新五次,而它只需要更新一次。

另一个是我不确定 FinalThrust 是否总是以正确的顺序计算。首先必须更新叶片,然后必须更新推力和风,然后才能计算最终推力。(我已经检查了我实际课程的结果,它们现在是正确的,但我不知道这是否会在将来导致错误)

最后,我想优化Fan,也就是把它放到一个循环中。如何判断所有更新是否已完成,以便检查输出值并进行下一次优化迭代?

在导致此之前我已经问过问题,答案是我应该创建一个状态机,但我不知道如何将状态机合并到其中。

我绝对比程序员更工程师!谢谢您的帮助 :)

4

1 回答 1

0

您可以从 Length 更新中触发事件。这可以增加一个计数器,当它达到 5(或者风扇上有许多叶片)时更新风扇。

这反过来会触发 FinalThrust 更新订阅的事件。同样,如果这需要其他先决条件,它可以设置一个标志,并且仅在设置所有标志时才发生更新。

You can continue this chaining firing an event out of the final link to indicate that everything is complete and the next iteration can commence.

于 2010-01-12T18:19:45.177 回答