2016-05-30 58 views
1

我是一個Windows窗體開發人員,我目前正忙着使用WPF。爲了快速比較文本框中的兩種文本渲染技術,我編寫了一個小程序,在窗口中創建大量文本框,並每100ms更新一次文本。緩慢的文本呈現與許多文本框

令我驚訝的是,測試應用程序的WPF版本呈現比WinForms版本慢得多。大多數情況下,應用程序完全不響應,例如,當我嘗試調整窗口大小時。該應用程序的WinForms版本運行平穩。

所以我的問題是:是否有問題的方式我使用WPF控件(我使用WrapPanel作爲控件容器在WPF和FlowLayoutPanel在WinForms中)?或者是文本渲染比WinForms真的慢?

WPF:

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Threading; 

namespace PerformanceTestWPF 
{ 
    public partial class MainWindow : Window 
    { 
     DispatcherTimer _timer = new DispatcherTimer(); 
     Random _r = new Random(); 

     public MainWindow() 
     { 
      InitializeComponent(); 

      for (int i = 0; i < 400; i++) 
       this.wrapPanel.Children.Add(new TextBox {Height = 23, Width = 120, Text = "TextBox"}); 

      _timer.Interval = new TimeSpan(0,0,0,0, 100); 
      _timer.Tick += _timer_Tick; 
      _timer.Start(); 

     } 

     private void _timer_Tick(object sender, EventArgs e) 
     { 
      foreach (var child in wrapPanel.Children) 
      { 
       var textBox = child as TextBox; 
       if (textBox != null) 
       { 
        textBox.Text = _r.Next(0, 1000).ToString(); 
       } 
      } 
     } 
    } 
} 

的WinForms:

using System; 
using System.Windows.Forms; 

namespace PerformanceTestWinforms 
{ 
    public partial class Form1 : Form 
    { 
     Timer _timer = new Timer(); 
     Random _r = new Random(); 

     public Form1() 
     { 
      InitializeComponent(); 

      for (int i = 0; i < 400; i++) 
       this.flowLayoutPanel1.Controls.Add(new TextBox { Height = 23, Width = 120, Text = "TextBox" }); 

      _timer.Interval = 100; 
      _timer.Tick += _timer_Tick; 
      _timer.Start(); 
     } 

     private void _timer_Tick(object sender, EventArgs e) 
     { 
      foreach (var child in flowLayoutPanel1.Controls) 
      { 
       var textBox = child as TextBox; 
       if (textBox != null) 
       { 
        textBox.Text = _r.Next(0, 1000).ToString(); 
       } 
      } 
     } 
    } 
} 
+0

這裏不會跳到結論。也許這是調度週期很昂貴。無法在我的機器上進行性能分析(需要更高的憑據);看看你能否做到這一點,找出哪些功能實際上是瓶頸。 –

回答

2

我認爲這個問題是明確的調度,試試這個結合基於例如:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Windows.Threading; 

namespace WpfPerfTest 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     Timer _timer; 
     Random _r = new Random(); 

     private readonly List<ValueViewModel<string>> _values = new List<ValueViewModel<string>>(); 

     public MainWindow() 
     { 
      InitializeComponent(); 

      for (int i = 0; i < 400; i++) 
      { 
       var value = new ValueViewModel<string>(); 
       var tb = new TextBox { Height = 23, Width = 120 }; 
       tb.SetBinding(TextBox.TextProperty, new Binding("Value") { Source = value }); 
       this.wrapPanel.Children.Add(tb); 
       this._values.Add(value); 
      } 

      _timer = new Timer(o => 
      { 
       foreach (var value in this._values) 
        value.Value = _r.Next(0, 1000).ToString(); 
      }, null, 0, 100); 
     } 
    } 

    class ValueViewModel<T> : INotifyPropertyChanged where T : class 
    { 

     private T _Value = default(T); 
     public T Value 
     { 
      get { return _Value; } 
      set 
      { 
       if (value != _Value) 
       { 
        _Value = value; 
        OnPropertyChanged("Value"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 


     protected virtual void OnPropertyChanged(string name) 
     { 
      this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 

在調整它仍然嗆相當有點,但除此之外,它表現更好。

+0

謝謝,這真的很好。但爲什麼在這裏調度速度更快(我猜這裏發生了某種隱式調度,因爲定時器現在是一個System.Threading.Timer,它異步執行回調)? – loki

+0

如果使用綁定,調度會隱式發生,因此可能會更有效地進行調度,或者將更新合併到現有的循環中。 WPF調度程序內部相當複雜,建議[本文](https://msdn.microsoft.com/en-us/library/ms741870%28v=vs.100%29.aspx)以獲取詳細信息。 –