wpf线程中更新UI的4种方式

news2024/12/27 13:28:57

        在wpf中,更新UI上面的数据,那是必经之路,搞不好,就是死锁,或者没反应,很多时候,都是嵌套的非常深导致的。但是更新UI的方式,有很多的种,不同的方式,表示的意思不一样,但是眼睛看到的,似乎是一回事。

首先我们创建一个简单的wpf程序

业务就是,一直点击确定,然后更新数据即可,比较简单,通过简单的案例来了解一个wpf中更新UI的4种方法。 

第一种:

点击确定后,界面先变化Hello WPF11,再变化Hello WPF12,并且界面可以任意拖动不卡。

这个方法是全局性质的。

using System.Windows;

namespace WpfApp6Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF11");
            });

            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF12");
            });
        }


        private void UpdateTextBlock(string text)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                txtUsername.Text = text;
            }));
        }

    }
}

第二种:

点击确定后,和前面的效果是一样的。

这个方法是当前界面性质的。

using System.Windows;

namespace WpfApp6Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF11");
            });

            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF12");
            });
        }


        private void UpdateTextBlock(string text)
        {
            //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            //{
            //    txtUsername.Text = text;
            //}));

            this.Dispatcher.Invoke(new Action(() =>
             {
                 txtUsername.Text = text;
             }));
        }

    }
}

第三种:

点击确定后,和前面的效果是一样的。

这个方法是当前控件性质的。

using System.Windows;

namespace WpfApp6Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF11");
            });

            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF12");
            });
        }


        private void UpdateTextBlock(string text)
        {
            //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            //{
            //    txtUsername.Text = text;
            //}));


            //this.Dispatcher.Invoke(new Action(() =>
            // {
            //     txtUsername.Text = text;
            // }));



            txtUsername.Dispatcher.Invoke(new Action(() =>
            {
                txtUsername.Text = text;
            }));

        }

    }
}

第四种: 

点击确定后,和前面的效果是一样的。

这个方法是当前控件性质的,但是还对当前控件进行是否有访问权限进行了判断。

using System.Windows;

namespace WpfApp6Demo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF11");
            });

            await Task.Run(() =>
            {
                // 耗时操作
                Thread.Sleep(2000);
                UpdateTextBlock("Hello WPF12");
            });
        }


        private void UpdateTextBlock(string text)
        {
            //System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
            //{
            //    txtUsername.Text = text;
            //}));


            //this.Dispatcher.Invoke(new Action(() =>
            // {
            //     txtUsername.Text = text;
            // }));



            //txtUsername.Dispatcher.Invoke(new Action(() =>
            //{
            //    txtUsername.Text = text;
            //}));

            if (!txtUsername.Dispatcher.CheckAccess())
            {
                txtUsername.Dispatcher.Invoke(new Action<string>(UpdateTextBlock), text);
            }
            else
            {
                txtUsername.Text = text;
            }

        }

    }
}

以上都是以同步Invoke的方式进行调用的,异步的话使用BeginInvoke。 

总结:通过案例,可以了解到,上面4种方式,对于此案例来说都可以达到最终的效果,但是那一种效果最好,并没有体现出来。博主认为:第三种最好,原因是从这个需求上考虑的,因为需求需要更新的就是txtUsername上面的数据,那么直接作用于它,对于资源的耗损,将是最少得。可能有人认为第四种方式最好,进行了线程判断,似乎更加的安全,那么您认为呢???

本文来源:

wpf线程中更新UI的4种方式-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1642525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

目标跟踪—卡尔曼滤波

目标跟踪—卡尔曼滤波 卡尔曼滤波引入 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的一项重要措施。是根据观察某一随机过程的结果&#xff0c;对另一与之有关的随机过程进行估计的概率理论与方法。 历史上最早考虑的是维纳滤波&#xff0c;后来R.E.卡…

anaconda、cuda、tensorflow、pycharm环境安装

anaconda、cuda、tensorflow、pycharm环境安装 anaconda安装 anaconda官方下载地址 本文使用的是基于python3.9的anaconda 接下来跟着步骤安装&#xff1a; 检验conda是否成功安装 安装CUDA和cuDNN 提醒&#xff0c;CUDA和cuDNN两者必须版本对应&#xff0c;否者将会出错…

SpringBoot---------Swagger

第一步&#xff1a;引入依赖 <!-- swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId></dependency> 第二步&#xff1a;配置文件 import com.sky.intercept…

Educational Codeforces Round 165 (Rated for Div. 2) (C、D)

1969C - Minimizing the Sum 题意&#xff1a; 思路&#xff1a;观察到操作数很小&#xff0c;最值问题操作数很容易想到dp&#xff0c;用表示第个元素&#xff0c;操作了次的最小值总和&#xff0c;转移的时候枚举连续操作了几次即可&#xff0c;而连续操作了几次即将全部变成…

微信小程序 uniapp家庭食谱菜谱食材网上商城系统小程序ko137

随着生活节奏的不断加快&#xff0c;越来越多的人因为工作忙而没有时间自己出去订购喜欢的菜品。随着Internet的飞速发展&#xff0c;网络已经成为我们日常生活中必不可少的部分&#xff0c;越来越多的人也接受了电子商务这种快捷、方便的交易方式。网上订餐其独有的便捷性和直…

GNU Radio创建FFT、IFFT C++ OOT块

文章目录 前言一、GNU Radio官方FFT弊端二、创建自定义的 C OOT 块1、创建 OOT 模块2、创建 OOT 块3、修改 C 和 CMAKE 文件4、编译及安装 OOT 块 三、测试1、grc 图2、运行结果①、时域波形对比②、频谱图对比 四、资源自取 前言 GNU Radio 自带的 FFT 模块使用起来不是很方便…

opengauss概述-基础知识篇-备考华为高斯

目录 &#x1f9e8;考前准备: &#x1f3a1;数据库操作语言 ✨OLTP和OLAP &#x1f3af;常用函数 &#x1f9f2;字符处理函数 关于 left 和 right 特别重点的字符串函数 &#x1f9f2;数字操作函数 关于 ceil 和 floor &#x1f9f2;时间和日期处理函数 &#x1f9f…

karpathy Let‘s build GPT

1 introduction 按照karpathy的教程&#xff0c;一步步的完成transformer的构建&#xff0c;并在这个过程中&#xff0c;加深对transformer设计的理解。 karpathy推荐在进行网络设计的过程中&#xff0c;同时利用jupyter notebook进行快速测试和python进行主要的网络的构建。 …

安卓 app icon大小 安卓app界面尺寸大小

移动应用的界面设计画布尺寸设计多大&#xff08;特别是Android&#xff09;、图标和字体大小怎么定、需要设计多套设计稿么、如何切图以配合开发的实现&#xff1f; 本篇将结合iOS和android官方的设计规范、搜集的资料以及工作中的摸索&#xff0c;来分享移动应用界面设计中的…

《Fundamentals of Power Electronics》——基础交流建模方法

PWM整流器小信号交流模型建模的主要步骤为&#xff1a; (a)利用小纹波近似的动态版本&#xff0c;建立与电感和电容波形的低频平均值有关的方程&#xff1b; (b)平均方程的扰动和线性化&#xff1b; (c)交流等效电路模型的建立。 以下图buck-boost电路为例进行分析。 首先测…

分类规则挖掘(一)

目录 一、分类问题概述&#xff08;一&#xff09;分类规则挖掘&#xff08;二&#xff09;分类规则评估&#xff08;三&#xff09;分类规则应用 二、k-最近邻分类法 一、分类问题概述 动物分类&#xff1a;设有动物学家陪小朋友林中散步&#xff0c;若有动物突然从小朋友身边…

电路板/硬件---器件

电阻 电阻作用 电阻在电路中扮演着重要的角色&#xff0c;其作用包括&#xff1a; 限制电流&#xff1a;电阻通过阻碍电子流动的自由而限制电流。这是电阻最基本的功能之一。根据欧姆定律&#xff0c;电流与电阻成正比&#xff0c;电阻越大&#xff0c;通过电阻的电流就越小。…

【机器视觉】C# .NET 8 部署yolov9 onnx对象检测

这段代码展示了一个使用YOLOv9进行对象检测的简单测试框架。代码主体以及其功能分为以下几个关键部分&#xff1a; 创建测试图片数组 _testImages&#xff0c;它包含了图片文件名和对应的标签。使用 buildTests 方法来从给定的文件名中加载图片并调整尺寸&#xff0c;准备测试数…

Linux搭建sqlilabs靶场

提前准备&#xff1a; 文章中所使用到的Linux系统&#xff1a;Ubantu20.4sqlilabs靶场下载地址&#xff1a;GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. 一. 安装phpstudy phpstudy安装命令&#xff1a;wget -O install.sh h…

【链表-双向链表】

链表-双向链表 1.链表的分类1.1 分类依据1.2 常用类型 2.双向链表的2.1 双向链表的结构2.2 双向链表的操作2.2.1 **初始化**2.2.2 **尾插**2.2.3 **头插**2.2.4 **尾删**2.2.5 **头删**2.2.6 在pos位置之后插入数据2.2.7 删除pos节点2.2.8 查找2.2.9 销毁 1.链表的分类 1.1 分…

Java如何获取当前日期和时间?

Java如何获取当前日期和时间&#xff1f; 本文将为您介绍 Java 中关于日期和时间获取的方法&#xff0c;以及介绍 Java 8 中获取日期和时间的全新API。 1、 System.currentTimeMillis() 获取标准时间可以使用 System.currentTimeMillis() 方法来获取&#xff0c;此方法优势是…

Qt与MySQL连接

QT连接Mysql数据库&#xff08;详细成功版&#xff09;-CSD N博客 我的MySQL是64位的&#xff0c;所以我的Qt的套件也需要是64位的 遇到的问题&#xff1a; &#xff08;available drivers中已经有QMYSQL QMYSQL3&#xff0c;还是not loaded&#xff09; QSqlDatabase: QMYS…

专项技能训练五《云计算网络技术与应用》实训7-1:安装mininet

文章目录 mininet安装1. 按6-1教程安装opendaylight控制器。2. 按6-2教程安装RYU控制器。3. 按5-1教程安装openvswitch虚拟交换机并开启服务。4. 将老师所给mininet安装包试用winSCP传送至电脑端。5. 安装net-tools。6. 安装mininet7. 安装完成后&#xff0c;使用命令建立拓扑&…

Jenkins集成Kubernetes 部署springboot项目

文章目录 准备部署的yml文件Harbor私服配置测试使用效果Jenkins远程调用参考文章 准备部署的yml文件 apiVersion: apps/v1 kind: Deployment metadata:namespace: testname: pipelinelabels:app: pipeline spec:replicas: 2selector:matchLabels:app: pipelinetemplate:metada…

腾讯云IM即时通信引入(React Web端组件式)

开发环境要求 React ≥ v18.0 &#xff08;17.x 版本不支持&#xff09; TypeScript node&#xff08;12.13.0 ≤ node 版本 ≤ 17.0.0, 推荐使用 Node.js 官方 LTS 版本 16.17.0&#xff09; npm&#xff08;版本请与 node 版本匹配&#xff09; chat-uikit-react 集成 …