c# – 通过将UI分解成“区域”来提高WPF性能 – 这是可能的吗?

c# – 通过将UI分解成“区域”来提高WPF性能 – 这是可能的吗?,第1张

概述我在 WPF客户端应用程序上执行了一个非常简单的性能测试: public partial class MainWindow : Window{ private ObservableCollection<int> data = new ObservableCollection<int>(); public ObservableCollection<int> DataObj { ge 我在 WPF客户端应用程序上执行了一个非常简单的性能测试:
public partial class MainWindow : Window{    private ObservableCollection<int> data = new ObservableCollection<int>();    public ObservableCollection<int> DataObj { get { return data; } }    private voID button1_Click(object sender,RoutedEventArgs e)    {        for (int j = 0; j < 5; j++)        {            Thread t = new Thread(() =>                {                    for (int i = 0; i < 100; i++)                    {                        Thread.Sleep(5);                        dispatcher.Invoke(new Action(() => { data.Add(1); })); //updates the count                        dispatcher.Invoke(new Action(() => { richTextBox1.AppendText("1"); })); //updates the string data                    }                });            t.Start();        }    }

然后我在UI中有两个控件:一个TextBlock和一个RichTextBox.

TextBlock绑定到数据源的Count属性,而RichTextBox将每个新的数据值追加到其文本字符串(即显示数据的内容).

如果我禁用RichTextBox绑定,TextBlock会很快更新,循环遍历.但是,启用RichTextBox绑定会减慢所有事情,两个控件都会以“globs”进行更新,也可能每秒更新一次或两次.换句话说,整个UI以RichTextBox绑定的速度运行.

有没有办法打破这种性能依赖性?我理解RichTextBox可能会很慢,但为什么它必须减慢否则减轻快速的TextBlock?

解决方法 WPF的具体内容是每个窗口只有一个UI线程.

虽然可以使用其他窗口,使其看起来像是当前应用程序的一部分(将windowstyle属性设置为None,更新位置和大小),但它看起来并不自然,并且有更好的方法来整理性能的问题.

众所周知,有必要使用dispatcher类来从后台线程更新UI. BeginInvoke方法具有DispatcherPriority类型的可选参数,它们具有以下值.

> SystemIDle
> ApplicationIDle
> ContextIDle
>背景
>输入
>加载
>渲染
> DataBind
>正常
>发送

默认值为normal(9),几乎是最高优先级,只要您调用不带参数的BeginInvoke方法,它就会被隐式应用.在您的示例中调用RichTextBox具有此优先级.

但是绑定到该属性并且未被手动更新的TextBlock具有较低的优先级DataBind(8),这就是为什么它被更新的速度更慢.

为了更快地绑定,可以减少调用RichTextBox的优先级,并设置低于8的值,例如Render(7).

dispatcher.Invoke(/*...*/,dispatcherPriority.Render);

这将有助于绑定,但UI不会响应鼠标点击,您甚至无法关闭窗口.

继续降低优先级:

dispatcher.Invoke(/*...*/,dispatcherPriority.input);

应用程序响应更好,但是在RichTextBox中填充文本时仍然无法输入内容.

所以最终的值是Background(4):

dispatcher.Invoke(new Action(() => { richTextBox1.AppendText("1"); }),dispatcherPriority.Background);
总结

以上是内存溢出为你收集整理的c# – 通过将UI分解成“区域”来提高WPF性能 – 这是可能的吗?全部内容,希望文章能够帮你解决c# – 通过将UI分解成“区域”来提高WPF性能 – 这是可能的吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1260445.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存