簡體   English   中英

System.StackOverflowException WPF MVVM

[英]System.StackOverflowException WPF MVVM

我正在嘗試使用MVVM在WPF中創建一個簡單的數字時鍾。 我有一個有綁定的標簽。 后面的代碼很簡單,每秒都會引發一個屬性更改事件,並且我有一個stackoverflow異常。 有人可以幫忙嗎?

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }
    private string _lblValue;
    public string LabelValue
    {
        get
        {
            UpdateLabel();
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged(LabelValue);
        }
    }

    private void UpdateLabel()
    {
        _lblValue = System.DateTime.Now.ToString();
        //System.Threading.Thread.Sleep(2000);
        OnPropertyChanged("LabelValue");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}

正如har07所解釋的那樣,它是一個無限的UI循環。 這是我對此問題的解決方法。

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        Task.Run(() => UpdateLabel());
    }

    private string _lblValue;
    public string LabelValue
    {
        get
        {
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged();
        }
    }

    private void UpdateLabel()
    {
        while (true)
        {
            LabelValue = System.DateTime.Now.ToString();
            System.Threading.Thread.Sleep(1000);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}

這是發生的事情:

  1. LabelValue的getter中調用UpdateLabel()函數
  2. UpdateLabel()調用OnPropertyChanged("LabelValue");
  3. 步驟2使UI檢查屬性LabelValue更新值,換句話說,它會導致調用LabelValue getter
  4. 回到第1步。

重復上述所有步驟,直到拋出stackoverflow異常。 嘗試刪除第2步以解決問題。

在你的情況下,最好使用間隔為一秒的計時器。
例如:

使用System.Timers;

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private Timer _clockTimer;

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

       _clockTimer = new Timer(1000); // The interval is in milliseconds
       _clockTimer.Elapsed += (sender, e) =>
       {
           LabelValue = System.DateTime.Now.ToString();
       };
    }

    private string _lblValue;
    public string LabelValue
    {
        get
        {
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged("LabelValue");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}


如果您對計時器有更多疑問,可以在MSDN上查看更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM