WPF加载大量控件的优化

2023-11-05

WPF 应用程序从两个线程开始:一个用于处理呈现,一个用于管理 UI。呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入、处理事件、绘制屏幕以及运行应用程序代码。

UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队。Dispatcher 基于优先级选择工作项,并运行每一个工作项,直到完成。每个 UI 线程都必须至少有一个 Dispatcher,并且每个 Dispatcher 都只能在一个线程中执行工作项。  而我们使用的基本上都是管理UI的线程,Dispatcher。

问题

     假如我们的程序只有一个线程处理UI,当UI需要渲染很多的控件时,界面就会出现假死的现象,这个时候就需要一个缓冲控件显示,直到UI渲染完成,可以继续接受输入,处理事件。

    那么问题来了,如果这个缓冲动画和主UI用的同一个Dispatcher,你的缓冲控件的动画也会假死。

    如何处理呢?

    
方案

1.将线程设置为应用程序空闲处理

Dispatcher.BeginInvoke(new Action(() =>
{
加载控件;
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);

2.提示等待框

在新线程中启动等待框

http://blog.csdn.net/steel_1991/article/details/54428525

3.启用虚拟化

VirtualizingStackPanel

实例

XAML

<Window x:Class="WpfApplication69.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="525"
        Loaded="Window_Loaded">
    <Window.Resources>
        <Storyboard x:Key="sb1">
            <DoubleAnimation Storyboard.TargetName="rectangle"
                             Storyboard.TargetProperty="(TextBlock.RenderTransform).(RotateTransform.Angle)"
                             From="0"
                             To="360"
                             Duration="0:0:1"
                             RepeatBehavior="Forever" />
        </Storyboard>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition  Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>

        <Rectangle Name="rectangle"
                   Width="20"
                   Height="20"
                   Fill="Blue"
                   Margin="5"
                   VerticalAlignment="Center">
            <Rectangle.RenderTransform>
                <RotateTransform Angle="0"
                                 CenterX="10"
                                 CenterY="10" />
            </Rectangle.RenderTransform> 
        </Rectangle>
        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Grid x:Name="gg">

        </Grid>
    </ScrollViewer>
    </Grid>
   
</Window>

C#

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ShowWnd();
        }
        private void ShowWnd()
        {
            Storyboard sb = (Storyboard)this.Resources["sb1"];
            sb.Begin(rectangle,true);

            Action a0 = NewMethod;
            Action a1 = NewMethod1;
            Action<int, int> a2 = NewMethod2;
            Action a = new Action(() =>
            {
                int count = 200;
                for (int i = 0; i < count; i++)
                {
                    this.Dispatcher.BeginInvoke(a1,DispatcherPriority.Background);
                    for (int j = 0; j < 250; j++)
                    {
                        if (i == 0)
                        {
                            this.Dispatcher.BeginInvoke(a0, DispatcherPriority.Background);
                        }
                        this.Dispatcher.BeginInvoke( DispatcherPriority.Background,a2, i, j);
                        System.Threading.Thread.Sleep(1);
                    }
                }


            });
            AsyncCallback callBack = new AsyncCallback((aa) =>
            {

                Action stop = new Action(() =>
                {
                  
                    sb.Stop(rectangle);
                });
                this.Dispatcher.Invoke(stop);
            });
            a.BeginInvoke(callBack, null);
            //Task t = Task.Factory.StartNew(a);

            //Action<Task> cont = new Action<Task>((tt) =>
            //{
            //    this.Background = Brushes.Yellow;
            //});
            //t.ContinueWith(cont);
        }

        private void NewMethod2(int i, int j)
        {

            Border bd = new Border();
            bd.BorderBrush = Brushes.Black;
            bd.BorderThickness = new Thickness(0.5);
            bd.Background = Brushes.Yellow;
            Grid.SetColumn(bd, j);
            Grid.SetRow(bd, i);
            gg.Children.Add(bd);
        }

        private void NewMethod1()
        {
            gg.RowDefinitions.Add(
                                new RowDefinition()
                                {
                                    Height = new GridLength(5, GridUnitType.Pixel)
                                }
                        );
        }

        private void NewMethod()
        {
            gg.ColumnDefinitions.Add(
                                          new ColumnDefinition()
                                          {
                                              Width = new GridLength(5, GridUnitType.Pixel)
                                          }
                                  );
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
           // ShowWnd();
        }

参考:

https://blog.csdn.net/steel_1991/article/details/54428525

https://blog.csdn.net/weixin_30707875/article/details/98324669

https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/threading-model?redirectedfrom=MSDN

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF加载大量控件的优化 的相关文章

随机推荐

  • 网络安全(黑客)自学的误区

    一 自学网络安全学习的误区和陷阱 1 不要试图先成为一名程序员 以编程为基础的学习 再开始学习 我在之前的回答中 我都一再强调不要以编程为基础再开始学习网络安全 一般来说 学习编程不但学习周期长 而且实际向安全过渡后可用到的关键知识并不多
  • Trie树【数组实现】

    全文目录 Trie的表现形式 数组实现 Trie 树 代码 Trie的表现形式 Trie树主要用来实现字符串的存储和快速查找 其表现形式类似一颗多叉树 每个节点表示字符串的一个字符 由于可能会存在类似 abc 和 abcde 这样的数据 所
  • 大数据和人工智能到底是什么关系

    大数据和人工智能的关系 首先要说什么是大数据 这些年来 大数据先是被神化 继而又被妖魔化 到了今天 其实谁也不知道别人所谓的大数据指的是什么 有时候大数据的定义里既有平台 硬件 又有分析技术 但为了说清楚大数据和人工智能的关系 我们还是回归
  • 下一波加密浪潮:站在风口上的“NFT”!

    如果说2020是区块链的 Defi 大火年 流动性挖矿让不少用户和平台完美体验了一场红利盛宴 那么2021则杀出的黑马 NFT 升级为主角 拉开了表演的序幕 不少项目和用户目光纷纷投向这一赛道 试图寻找新的财富机遇 NFT定义 它究竟是什么
  • 特征脸EigenFace、Fisher脸FisherFace、LBP直方图LBPHFace

    在最新版的2 4 2中 文档的更新也是一大亮点 refrence manual扩充了200多页的内容 添加了contrib部分的文档 contrib就是指OpenCV中新添加的模块 但又不是很稳定 可以认为是一个雏形的部分 这次结合refm
  • 【NLP】使用 PyTorch 通过 Hugging Face 使用 BERT 和 Transformers 进行情感分析

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Android 项目必备(十二)--> APP 底部导航栏最佳实践

    文章目录 简介 TabLayout Fragment 1 效果图 2 布局文件 3 代码 BottomNavigationView Fragment 1 效果图 2 布局文件 3 main bottom navigation xml 4 代
  • Python实现拉格朗日插值法填补缺失值

    s为列向量 n为被插值的位置 k为取前后的数据个数 默认为5 from scipy interpolate import lagrange 导入拉格朗日插值函数 def ployinterp column s n k 5 y s iloc
  • 每日技巧(word条形图更改横坐标)

    问题 在工作中 遇到条形图需要更改纵坐标的数据 那该如何解决这个问题呢 解决方案 右键 选中编辑数据中的在Excel中编数据 D 点击完成后会出现 如下图的Excel的表格 数据编辑完成后 则横坐标则会改变 如下图 今日小技巧到此为止
  • 消息队列 RabbitMQ入门:Linux(Docker)中安装和卸载RabbitMQ服务

    文章目录 前言 一 Linux中安装RabbitMQ 下载Erlang 下载RabbitMQ 进入Linux进行安装 启动RabbitMQ 二 RabbitMQ Web管理页面 安装RabbitMQ Web管理页面 访问管理页面 三 使用D
  • 协同过滤算法_《推荐系统实践》3.基于物品的协同过滤算法

    基于物品的协同过滤算法 item based collaborative filtering 以下简称ItemCF 算法思想 给用户推荐那些和他们之前喜欢的物品相似的物品 不过 ItemCF算法并不利用物品的内容属性计算物品之间的相似度 它
  • android二级菜单ui,Android UI 之实现多级树形列表TreeView示例

    所谓TreeView就是在Windows中常见的多级列表树 在Android中系统只默认提供了ListView和ExpandableListView两种列表 最多只支持到二级列表的实现 所以如果想要实现三级和更多层次的列表 就需要我们自己来
  • python pandas使用pipe管道增强代码可读性

    pandas dataframe的pipe文档链接 https pandas pydata org docs reference api pandas DataFrame pipe html 使用pipe可以像水流一样 有顺序的执行data
  • 三子棋【C语言实现】

    三子棋 让我们一起用C语言来玩一场三子棋的游戏吧 文章目录 三子棋 前言 一 基本步骤 二 具体实现 1 菜单界面 2 创建棋盘 3 棋盘初始化 4 打印棋盘 5 玩家落子 6 电脑落子 7 判断输赢 8 运行演示 1 玩家获胜 2 电脑获
  • Android apk安装管理(PackageManagerService 分析)

    Android apk安装管理 PackageManagerService 分析 本篇主要分析了系统启动阶段包管理服务的启动流程 其中的几个接口在apk安装时也会被调用 包管理服务启动时主要做的工作大致有如下几方面 1 建立java层的in
  • python安装pywin32报错问题的解决。

    前几天在win7系统安装pywin32 报错提示dll动态库找不到 在网上查找各种资料 均未解决 后来发现是缺少vcruntime140 1 dll 下载后复制到Windows的system32文件夹下 完美解决 注意是vcruntime1
  • python机器学习模型选择&调参工具Hyperopt-sklearn(1)——综述&分类问题

    针对特定的数据集选择合适的机器学习算法是冗长的过程 即使是针对特定的机器学习算法 亦需要花费大量时间和精力调整参数 才能让模型获得好的效果 Hyperopt sklearn可以辅助解决这样的问题 主页 http hyperopt githu
  • python学习:静态方法,类方法,property装饰,抽象类

    1 静态方法 关键词为 staticmethod def func 在类实例化之前使用 如Class func 使用场景 如检测是否满足实例化的条件 2 类方法 关键词为 classmethod def func return cls 类方
  • Android使用ProgressBar实现加载动画

    项目需要做一个加载转圈的效果 给了一张菊花图 首先想到的是使用补间动画的旋转效果 在anim目录中创建loading xml
  • WPF加载大量控件的优化

    WPF 应用程序从两个线程开始 一个用于处理呈现 一个用于管理 UI 呈现线程有效地隐藏在后台运行 而 UI 线程则接收输入 处理事件 绘制屏幕以及运行应用程序代码 UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队 Di