Winform SynchronizationContext多线程更新画面控件

news/2024/7/7 21:00:17/文章来源:https://www.cnblogs.com/HomeSapiens/p/18282183

  SynchronizationContext在通讯中充当传输者的角色,实现功能就是一个线程和另外一个线程的通讯。

  需要注意的是,不是每个线程都附加SynchronizationContext这个对象,只有UI线程是一直拥有的。故获取SynchronizationContext也只能在UI线程上进行SynchronizationContext context = SynchronizationContext.Current;

  那什么时候会用到呢?

  在多线程操作时往往需要切回某个线程中去工作,等完成后再切回来。

  如主UI线程中创建了一个子线程A。A中添加了委托事件。UI线程中向A线程的类注册了事件,当A线程触发事件时去修改UI上的属性如TEXT。

  这个时候往往要在UI线程向子线程注册的事件方法中使用控件的invoke方法才能访问UI线程中的控件,因为这些注册的事件(委托)方法代码虽然看似写在UI线程的Form类中,但实际上是注册在了子线程A的事件中,它们是会被子线程A触发事件时在子线程内部执行的。这样,我们不得不在主UI线程的类的注册事件方法中通过控件的Invoke方法才能访问控件,这样做十分麻烦。我们想和系统的控件事件一样,直接在注册的事件方法中访问控件。那么这个时候就可以用SynchronizationContext了。

  SynchronizationContext.Send(SendOrPostCallback d,object state);

  SynchronizationContext.Post(SendOrPostCallback d,object state);

  d 为一个没有返回值,并且具有一个Object类型传入参数的委托(SendOrPostCallback );

  state 为执行这个委托时的参数(object);

注意:

  SynchronizationContext的对象不是所有线程都被附加的,只有UI主线程会被附加。

  对于UI线程来说,是如何将SynchronizationContext这个对象附加到线程上的呢?

  在Form1 form = new Form1()之前,SynchronizationContext对象是为空,而当实例化Form1窗体后,SynchronizationContext对象就被附加到这个线程上了。

  所以可以得出答案了:当Control对象被创建的同时,SynchronizationContext对象也会被创建并附加到线程上。所以在使用时,一定要等窗体InitializeComponent(); 这个完成后 它才能得到一个不是NULL的对象.

  

  那么SynchronizationContext的Send()和Post()二个方法有什么区别呢?

  Send() 是简单的在当前线程上去调用委托来实现(同步调用)。也就是在子线程上直接调用UI线程执行,等UI线程执行完成后子线程才继续执行。

  Post() 是在线程池上去调用委托来实现(异步调用)。这是子线程会从线程池中找一个线程去调UI线程,子线程不等待UI线程的完成而直接执行自己下面的代码。

  

例子:

复制代码
        /// <summary>/// 这里需要在主线程里定义,/// 并在主线程获得context = SynchronizationContext.Current/// </summary>private SynchronizationContext context;/// <summary>/// 窗体加载/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Load(object sender, EventArgs e){//此处就是之前提的在主线程获得SynchronizationContextcontext = SynchronizationContext.Current;//之后可以开线程了Thread thread = new Thread(new ThreadStart(Start));thread.IsBackground = true;thread.Start();}/// <summary>/// 线程操作/// </summary>private void Start(){ for(int i=0;i<100;++i){//这边即可正常调用主界面的控件了context.Send(operation, i);//正确//按原先直接应用,因为使用到控件会报错operation(i);//报错Thread.Sleep(100);}}/// <summary>/// 线程操作/// </summary>/// <param name="obj"></param>private void operation(object obj){textBox1.AppendText(obj.ToString() + "\r\n"); }
复制代码

 

 

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

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

相关文章

复数与复变函数选题

【参考】《复变函数论》钟玉泉编 《复变函数论学习指导书》钟玉泉编

Kubernetes基于helm安装 harbor

Kubernetes基于helm安装 harbor 之前harbor的安装都是借助docker完成一键安装部署,安装完成之后harbor组件均运行到一台机器上面,本文实践harbor在k8s环境中的部署。 准备工作 根据harbor官方要求:Kubernetes cluster 1.20+ Helm v3.2.0+结合ingress-nginx版本要求,建议K8S…

pdf的表格怎么转换成word?

Adobe设计PDF文件格式的目的是支持跨平台、多媒体集成的信息出版和发布,特别是对网络信息发布的支持。为了实现这一目标,PDF具有许多其他电子文件格式无法比拟的优势。如今,越来越多的电子书籍、产品描述、公司通知、网络数据和电子邮件开始使用PDF格式文件。但是PDF却不能直…

高效存储的秘诀:bitmap 数据结构在标签中的应用

在当今大数据和信息爆炸的时代,如何有效地管理和查询海量的数据成为了企业和开发者面临的重大挑战。其中,标签系统作为数据管理中的一种重要手段,被广泛应用于用户画像、商品分类、内容推荐等多个场景。然而,随着标签数量的急剧增加,传统的数据存储和查询方式已难以满足高…

2024年值得收藏的几款开源主机安全系统hids

随着云技术的迅速发展,主机安全系统HIDS作为服务器安全的最后一道防线,无论传统的硬件厂商,还是各大云厂商如阿里、腾讯云非常重视并闷声发大财。HIDS主机安全开源的项目虽多,但能实际用的极少,笔者经过大量搜索,找到以下几款优秀的产品供大家参考: 1、OpenHFWOpenHFW全…

代码随想录算法训练营第四十六天 | 买卖股票的最佳时机

121.买卖股票的最佳时机 题目链接 文章讲解 视频讲解动规五部曲:dp[j][0]: 表示持有股票的最大现金,dp[j][1]表示不持有股票的最大现金 递推公式:第j天持有股票的最大现金为:之前就持有这只股票和今天持有这只股票取最大值: dp[j][0] = max(dp[j-1][0], -prices[j]); 第j天…

Asp.Net Core -Authorizationz授权

授权的内部实现参考 动态授权参考动态授权 基于权限的授权 1.定义权限-Permissionspublic class Permissions{public const string Admin = "Admin";public const string Users = "Users";public const string UserCreate = Users+ ".Create";pu…

结对项目

命令行参数处理: 使用 argparse 或者 sys 模块处理命令行参数,以接收用户输入的题目数量和题目范围(例如最大数值)。 生成四则运算题目: 随机生成题目,每个题目包括两个操作数和一个运算符。 控制生成的题目数量和数值范围,确保生成的题目符合小学生的学习要求(比如操作…

详解微服务应用灰度发布最佳实践

本次分享是站在 DevOps 视角的灰度发布实践概述,主要内容包括以下四个方面:第一,灰度发布要解决的问题;第二,灰度发布的四种典型场景;第三,如何把灰度发布融入到应用的研发流程中,即把灰度发布与 DevOps 工作融合;第四,对于外部流量灰度场景,演示如何通过工具将其落…

OpenBMB Hugging Face THUNLP,联袂献上经典大模型课

这个夏天,THUNLP 携手 Hugging Face 和 OpenBMB,推出 大模型公开课第二季。在大模型公开课第二季中,将有全球知名开源社区 OpenBMB X Hugging Face 梦幻联动;MiniCPM、ChatDev、Ultra对齐 等明星开源项目作者亲自授课,带领同学从深度学习开始快速了解大模型的相关理论并进…

nginx开启https

生成自签名证书 如果是在运营商处获得的证书,则不用这一步点击查看代码 mkdir /etc/nginx/ssl cat > /etc/nginx/ssl/nginx.cnf <<EOF [ req ] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext x509_extension…

(三)JS逆向——爬取易车网

爬取易车网的车辆配置信息 所以主要就是确定这几个是怎么生成的 搜索x-sign值的位置,打断点,找到构建x-sign的函数 注意,一定要看清是否是正确的url,x-timestamp明显是时间戳 进入这个函数 x-sign值,是对这个字符串做md5,这个字符串由三部分构成,参数、时间戳、和一个固…

.Net知识技能大全

.Net知识技能大全 更多请见https://www.dotnetshare.com C#常见运算符一元运算符(+、-、!、~、++、--) 算术运算符(*、/、%、+、 – ) 移位运算符(<< 、>> ) 关系和类型测试运算符(==、!=、<、>、<=、>=、is 和 as) 逻辑运算符(&、^ 和 |…

Hello World with solidity

1. Solidity 是什么? Solidity 是一种面向对象的、静态类型的编程语言,专为在以太坊上编写智能合约而创建。由于以太坊上的智能合约可以处理真实世界的资产(比如加密货币),所以Solidity的设计非常关注安全性。 以下是 Solidity 的一些主要特点:类型安全和静态类型:这可以…

如何从Salesforce顾问转型为解决方案架构师?

在充满活力的Salesforce咨询领域,许多专业人士都希望从顾问转型为解决方案架构师。这种转型不仅需要掌握新技能,还需要从根本上改变思维方式。关键在于摆脱顾问典型的以职能为中心的思维模式,拥抱更广阔、更具战略性的视角。 从“如何”到“为什么” 当我们开始问“为什么”…

Modbus转Profibus主站网关连接温控表通讯技术

Modbus转ProfibusDP主站网关(XD-MDPBM20)是实现不同通讯协议设备之间联系的重要组件。本文将介绍Modbus转ProfibusDP主站网关(XD-MDPBM20)连接温控表实现高效通讯,涉及设备准备、协议介绍、配置步骤、测试通讯及注意事项。此技术可帮助实时监测温度并调节控制,提高生产效…

加解密技术原理

加解密技术概览 加解密定义 加密:数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,通过这样的途径来达到保护数据不被非法人员窃取、阅读的目的。解密:数据解密的过程就是对密文使用相应的算法和密钥进行解…

Jmeter使用CLI模式进行负载测试的注意点

在我们打开Jmeter的时候,窗口会出现如下提示:这个提示的意思是, 不要使用 GUI 模式进行负载测试:GUI 模式主要用于创建和调试测试,而不是运行大规模的负载测试。 ​使用 CLI 模式进行负载测试:CLI 模式(以前称为 NON GUI 模式)更适合进行负载测试,因为它能够更高效地使…

Golang面试:泛型

Go语言在1.18版本中引入了泛型(Generics),这是Go语言发展中的一个重要里程碑。泛型允许你编写更通用和可复用的代码,而无需牺牲类型安全性。以下是对Go中泛型的详细介绍,包括其语法、使用场景和示例代码。 1. 泛型的基本概念 泛型允许你定义可以处理多种数据类型的函数和数…

【算法】KD-tree

1. 算法简介 KD-tree(K-Dimensional),是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。 主要应用于多维空间关键数据的搜索。 KD-tree 的本质是一棵平衡树,将空间内的区域划分为一个超长方体,然后存储为节点进行维护。 以下为一个 \(k=2\) 时的 KD…