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表达式代替方法

总结

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

这就是经典。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTF-show WEB入门--web19

今晚web19也就顺便解决了 老样子我们先打开题目看看题目提示: 可以看到题目提示为: 密钥什么的,就不要放在前端了 然后我们打开题目链接: 然后我们查看网页源代码: 可以发现有用的内容全在网页源代码里。 前端验证…

将markdown格式内容在界面中展示出来(搭配上一篇使用)

1.定义一个div content 是你向展示的 markdown 格式数据 <div id"previewMarkdown"><textarea>{{ content }}</textarea> </div>2.导入js 这个都是 lib 目录下的 js 文件&#xff0c;因为 markdown 组件依赖这些 js 文件 <script src…

红外避障模块

目录 一、模块原理 二、模块使用说明 三、材料准备 四、代码 五、实验效果 实验效果 自动灯效果&#xff1a; 避障模块-CSDN直播 一、模块原理 红外避障模块利用光反射原理&#xff0c;模块前端拥有一个红外发射管和一个红外接收管。模块通电后红外发射管向前方不断发射…

vue前端RSA使用公钥进行加密,公钥进行解密

记录下RSA使用公钥进行加密&#xff0c;公钥进行解密&#xff1a; 背景&#xff1a;由于项目要求前后端进行数据加密传输&#xff0c;具体数据使用aes进行加密&#xff0c;aes密钥使用rsa进行加密&#xff0c;加密后的aes密钥放在请求头和响应头进行传输。这里实现的是前端vue…

springboot159基于springboot框架开发的景区民宿预约系统的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

net start mysql服务名无效|发生系统错误 解决办法

未输入正确的mysql服务名 解决办法&#xff1a; 使用net start命令查看可用的服务名&#xff0c;找到mysql的服务名 未使用管理员身份运行命令提示符 解决方法&#xff1a; 使用管理员身份运行命令提示符

十分钟GIS——geoserver+postgis+udig从零开始发布地图服务

1数据库部署 1.1PostgreSql安装 下载到安装文件后&#xff08;postgresql-9.2.19-1-windows-x64.exe&#xff09;&#xff0c;双击安装。 指定安装目录&#xff0c;如下图所示 指定数据库文件存放目录位置&#xff0c;如下图所示 指定数据库访问管理员密码&#xff0c;如下图所…

opensuse安装百度Linux输入法

前言 Linux下有输入法&#xff0c;拼音&#xff0c;百度的都有&#xff0c;但是用起来总感觉不如在windows下与安卓中顺手。 目前搜狗与百度都出了Linux的输入法&#xff0c;但是没有针对OpenSUSE的&#xff0c;只有ubuntu/deepin/UOS的安装包。 本文主要讲的如何把百度Linux输…

2024.2.6日总结(小程序开发3)

页面配置 页面配置和全局配置的关系&#xff1a; 小程序中&#xff0c;app.json中的window节点&#xff0c;可以全局配置小程序中每个页面的窗口表现 如果某些小程序想要有特殊的窗口表现&#xff0c;可以用页面级别的.json配置文件实现这个需求 页面配置和全局配置冲突时&…

嵌入式软件bug分析基本要求

摘要&#xff1a;软件从来不是一次就能完美的&#xff0c;需要以包容的眼光看待它的残缺。那问题究竟为何产生&#xff0c;如何去除呢&#xff1f; 1、软件问题从哪来 软件缺陷问题千千万万&#xff0c;主要是需求、实现、和运行环境三方面。 1.1 需求描述偏差 客户角度的描…

手撕spring bean的加载过程

这里我们采用手撕源码的方式&#xff0c;开始探索spring boot源码中最有意思的部分-bean的生命周期&#xff0c;也可以通过其中的原理理解很多面试以及工作中偶发遇到的问题。 springboot基于约定大于配置的思想对spring进行优化&#xff0c;使得这个框架变得更加轻量化&#…

Redis-布隆过滤器解决穿透详解

本文已收录于专栏 《中间件合集》 目录 背景介绍概念说明原理说明解决穿透安装使用安装过程Redis为普通安装的配置方式Redis为Docker镜像安装的配置方式 具体使用控制台操作命令说明Spring Boot集成布隆过滤器 总结提升 背景介绍 布隆过滤器可以帮助我们解决Redis缓存雪崩的问题…

【JS逆向学习】今日头条

逆向目标 目标网页&#xff1a;https://www.toutiao.com/?wid1707099375036目标接口&#xff1a;https://www.toutiao.com/api/pc/list/feed目标参数&#xff1a;_signature 逆向过程 老规矩先观察网络请求&#xff0c;过滤XHR请求观察加密参数&#xff0c;发现Payload的_s…

从蜗牛到超光速:Python 加速Playwright安装过程

目录 1. Python Playwright 安装简介2. 镜像加速的概念3. Python Playwright 镜像加速的必要性4. Python 安装 playwright5. 如何使用镜像加速安装 Python Playwright6. 总结 1. Python Playwright 安装简介 Python Playwright 是一个用于自动化 Web 浏览器交互的库它支持多种…

【C语言】三子棋游戏实现代码

目录 1.三子棋代码功能介绍 2.三子棋游戏实现步骤 ①打印菜单栏 ②判断是否进入三子棋游戏 ③三子棋游戏基本函数实现 &#xff08;1&#xff09;清空&#xff08;初始化&#xff09;棋盘函数实现 &#xff08;2&#xff09;打印棋盘函数实现 &#xff08;3&#xff0…

科研绘图-半小提琴图-

文章目录 前言1.软件安装-Origin 20222.绘制半小提琴图3.绘制径向条形图 前言 本文叙述记录的是一些科研绘图的实现方法&#xff0c;具体介绍从软件安装到实现图表绘制的详细过程。 1.软件安装-Origin 2022 Origin是一款具有丰富绘图功能的科研绘图软件&#xff0c;安装过程…

【Leetcode】1696. 跳跃游戏 VI

文章目录 题目思路代码结果 题目 题目链接 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 一开始你在下标 0 处。每一步&#xff0c;你最多可以往前跳 k 步&#xff0c;但你不能跳出数组的边界。也就是说&#xff0c;你可以从下标 i 跳到 [i 1&#xff0c; min(n -…

Kuberntes权威指南

一、目录 二、Kubernetes入门 三、Kubernetes核心原理 四、Kubernetes开发指南 五、Kubernetes运维指南 六、Kubernetes高级案例进阶 七、Kubernetes源码导读

【BIAI】Lecture 12 - Emotion in Brain AI

Emotion in Brain & AI 专业术语 Limbic system 边缘系统 Amygdala 杏仁核 temporal lobe 颞叶 hippocampus 海马体 Central Nucleus 中央核 medial amygdala 内侧杏仁核 ventral periaqueductal gray 腹侧中脑导水管周围灰质 课程大纲 What is emotion 当大脑检测到某些具…