与许多正文框的慢文本翻译

时间:2016-05-30 13:18:49

标签: .net wpf winforms performance

我是Windows Forms开发人员,目前我正在使用WPF。为了对文本框中文本呈现的两种技术进行快速性能比较,我编写了一个小程序,在窗口中创建了大量文本框,并每100ms更新一次文本。

令我惊讶的是,测试应用程序的WPF版本比WinForms版本慢得多。大多数情况下,应用程序根本没有响应,例如当我尝试调整窗口大小时。该应用程序的WinForms版本运行顺利。

所以我的问题是:我使用WPF控件的方式有什么问题(我使用WrapPanel作为WPF中的控件容器和WinForms中的FlowLayoutPanel)?或者文本呈现真的比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();
                }
            }
        }
    }
}

1 个答案:

答案 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));
        }
    }
}

在调整大小期间,它仍然会窒息,但除此之外它表现得更好。