C#委托的前世今生

起因

很多C#初学者,都遇到过这样的问题——线程间操作无效,从不是创建控件的线程访问它。

今天就这个问题,展开分析。

溯源

先说下这个问题产生的根源。

大家都知道,程序运行起来之后,首先会有一个主线程,主线程用于处理控件生成、界面渲染、事件响应、逻辑处理等操作,因此我们可以理解为窗体里的控件是属于主线程的。

我们也知道多线程,如果我们想实现与主线程同时执行另一件事,一般会去使用多线程。

因此多线程,从某种意义上来说,它和主线程都属于“线程”这个家族,他们的身份是“平等”的,就像你和你同事之间的关系一样。

那么,试想一下,如果你同事有一天想从你手上把你的PLC或者上位机项目程序拿过去,你愿不愿意?

 所以,如果在多线程里操作主线程的控件,你觉得主线程会不会答应,当然不会,主线程不答应的最直接表现就是,它会直接给一个报错,权当警告,如下图所示:

解决

那么如何解决呢?

你的同事如果非要拿到你的程序,他会想,硬的不行,就来软的。

所以他会找到你们共同的领导,跟你们领导这样说:“我手头上的这个100万的项目,能给公司带来50%的利润,现在需要用到他之前那个项目里的一个小知识,需要他把程序给我参考一下”。

在公司利益面前,你觉得你的领导会怎么办?

于是,领导和你“商量”了一下,毋庸置疑,你妥协了。

你的同事使用的招数叫做——委托。

那么,现在回到之前的问题上来,现在多线程要操作主线程的控件,是不是也可以使用委托来实现?

前世

委托定义:委托(Delegate) 是对某个方法的引用的一种引用类型变量。

如果这句话看不懂,那就别看了,跟着我动手做。

1、声明委托

委托声明需要根据执行的方法来定,严格来说,就是根据执行方法的返回值和参数,我们只是给窗体的Text设置一个固定值而已,因此我们的参数是空,返回值也为空。

声明委托如下:

2、创建委托对象

委托严格来说是一种类型,就像类一样,如果想要调用某个类,必须要创建一个该类的对象,所以我们要创建一个委托对象:

3、创建委托方法

委托对象也只是一个对象而已,就像领导一样,领导是不可能干活的,最终干活还得靠底下的兵来干,所以我们还得招人去干活。

招人干活就是委托方法,我们现在这个活很简单,所以我们的方法也很简单。

4、委托绑定

我们招到了一个“兵”,现在也有一个部门领导,怎么把他们联系起来呢?

很简单,让人事把这个兵分到这个部门就行了,这个分配的过程就是委托绑定,代码如下:

5、委托调用

万事俱备,只欠东风,终于干活了。

作为公司的老板,一般是不可能跟员工打交道的,他会把任务分配给部门领导,部门领导会把活再分配下去,所以我们委托调用,也是调用委托对象。

以上五步,就是委托的实现过程。

然而,我们运行之后,还是会报错。

没有那么简单的事!

因为想要在多线程里操作主线程的控件,你还得经过控件的同意,怎么经过控件同意呢?

控件的父类Control提供了一个这样的方法:

 意思就是说,想要操作控件,必须要通过Invoke方法来实现,Invoke方法里参数是一个委托,于是,我们只能灰溜溜地,这样写:

 果然,按照规矩来,就能达到效果:

今生

微软从某个版本开始,出来了Action和Lamda表达式,Action是系统委托,也就是说,不需要我们手动创建委托了,它有个兄弟叫Func,Action没有返回值,最多可以有16个参数,Func必须要有返回值,最多可以有16个参数,最后一个参数表示返回值。

于是我们开始简化:

第一步简化:用Action作为委托来创建

 第二步简化:委托对象只用一次,所以可以直接放到参数里

 第三步简化:用Lamda表达式代替方法

总结

我们所以常写的那行代码,其实只是一种简写方式而已,委托的五步法,不管怎么简化,怎么优化,其实本质还是一样,都离开不了这五个步骤。

这就是经典。

都看到这里了,是不是要点个赞呢?

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

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

相关文章

中小型网络系统总体规划与设计方法

目录 1.基于网络的信息系统基本结构 2.网络需求调研与系统设计原则 3.网络用户调查 4.网络节点地理位置分布情况 5.网络需求详细分析 6.应用概要分析 7.网络工程设计总体目标与设计原则 8.网络结构与拓扑构型设计方法 9.核心层网络结构设计 10.接入核心路由器 11.汇聚…

Android 环境搭建

1、桥接工具安装 网站地址:AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 使用安装包: adb 查看当前链接成功的设备:adb devices 使用adb shell指令来进入到手机的后台:

Redis 持久化对性能有何影响?

Redis 持久化对性能的影响 Redis 是一个高性能的内存数据存储系统,通常被用于缓存、消息队列和数据存储等方面。由于 Redis 是基于内存的,因此它的读写速度非常快,可以满足高并发、低延迟的应用需求。但是,当 Redis 需要持久化数…

探索STM32CubeMX:图形化工具简化嵌入式软件开发

STM32CubeMX是由STMicroelectronics提供的一款图形化工具,旨在简化STM32微控制器的嵌入式软件开发过程。它提供了一种快速、直观的方式来生成初始化代码并配置STM32微控制器,帮助开发人员节省宝贵的开发时间,并降低入门门槛。本文将探索STM32…

政安晨:快速学会~机器学习的Pandas数据技能(四)(汇总与映射)

从数据中提取价值! 概述 在上一篇文章中,我们学习了如何从DataFrame或Series中选择相关数据。从我们的数据表示中选择正确的数据对于完成工作非常重要,正如我们在练习中所演示的那样。 然而,数据并不总是以我们想要的格式直接从…

【力扣】两数之和,暴力枚举 + 哈希表

两数之和原题地址 方法一:暴力枚举 首先,我们需要枚举数组中所有可能的下标对组合,对于 n 个数的数组,从中选两个下标,有 种可能。做法很简单,遍历数组中的所有元素,对于每一个元素&#xff…

【Java EE】----SpringBoot的日志文件

1.SpringBoot使用日志 先得到日志对象通过日志对象提供的方法进行打印 2.打印日志的信息 3.日志级别 作用: 可以筛选出重要的信息不同环境实现不同日志级别的需求 ⽇志的级别分为:(1-6级别从低到高) trace:微量&#…

【QT+QGIS跨平台编译】之三十一:【FreeXL+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、FreeXL介绍二、文件下载三、文件分析四、pro文件五、编译实践一、FreeXL介绍 【FreeXL跨平台编译】:Windows环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台编译】:Linux环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台…

【JS逆向五】逆向模拟某网站的生成的【jsonKey】值 仅供学习

逆向日期:2024.02.07 使用工具:Node.js 加密方法:AES 文章全程已做去敏处理!!! 【需要做的可联系我】 可使用AES进行解密处理(直接解密即可):在线AES加解密工具 1、打开…

多路服务器技术如何处理大量并发请求?

在当今的互联网时代,随着用户数量的爆炸性增长和业务规模的扩大,多路服务器技术已成为处理大量并发请求的关键手段。多路服务器技术是一种并行处理技术,它可以通过多个服务器同时处理来自不同用户的请求,从而显著提高系统的整体性…

彩虹系统7.0免授权+精美WAP端模板源码

最低配置环境 PHP7.2 1、上传源码到网站根目录,导入数据库文件 2、修改数据库配置文件:/config.php 3、后台:/admin 账号: 4、前台用户:123456 密码:1234561

【lv5-7】

bootloader 在操作系统运行前的一小段代码,将软硬件环境初始化到一个合适的状态,为操作系统的加载和运行做好准备。 bootloader ->初始化软硬件环境 ->引导加载linux内核 ->给linux内核传参 ->执行用户命令 bootload是启动程序的总称&#x…

2 月 7 日算法练习- 数据结构-树状数组上二分

问题引入 给出三种操作, 0在容器中插入一个数。 1在容器中删除一个数。 2求出容器中大于a的第k大元素。 树状数组的特点就是对点更新,成段求和,而且常数非常小。原始的树状数组只有两种操作,在某点插入一个数和求1到i的所有数的…

合并分支rebase和merge的区别

文章目录 一、前言1.1、master分支1.2、dev分支 二、合并2.1、git merge2.2、git rebase 三、总结四、最后 一、前言 实际开发工作的时候,我们都是在自己的分支开发,然后将自己的分合并到主分支,那合并分支用2种操作,这2种操作有…

使用QT编写一个简单QQ登录界面

widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//设置窗口标题this->setWindowTitle("QQ");//设置窗口图标this->setWindowIcon(…

TCP的连接和断开详解

目录 1.TCP基础知识 1.1.TCP 头格式 1.2.TCP协议介绍 1.3.UDP协议介绍 1.4.TCP 和 UDP 区别 1.5.TCP 和 UDP 应用场景 1.6.计算机网络相关术语(缩写) 2.TCP 连接建立:三次握手 2.1.TCP 三次握手过程 2.2.三次握手原理 2.3.异常分析…

Python||数据分析与可视化_使用折线图分析各个城市的P.M.2.5月度差异情况(下)及使用堆叠柱状图对各个城市的PM2.5日均值情况进行数据分析与可视化

目录 1.使用Python折线图对各个城市的P.M.2.5月度差异情况进行数据分析与可视化。 2.使用Python堆叠柱状图对各个城市的PM2.5日均值情况进行数据分析与可视化。 1.使用Python折线图对各个城市的P.M.2.5月度差异情况进行数据分析与可视化。 import numpy as np import pandas a…

Python进程之并行与并发的区别

并行 : 当系统有一个以上CPU时,则进程的操作有可能非并发。当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行。 并发 : 当有多个进程在操作时&…

Optimism Collective 为 Covalent Network(CQT)提供价值 20 万美元的生态系统资助

Covalent Network(CQT) 是 Web3 生态系统中关键的“数据可用性”层,在与 Optimism Collective 多年的合作中取得了骄人的成果。Covalent Network(CQT)对于 Optimism 跨链数据的增长产生了直接的影响,而这一…