当前位置:网站首页>C# 窗体与子线程数据交互
C# 窗体与子线程数据交互
2022-07-29 20:05:00 【biyusr】
一般来说窗体上的UI在默认情况下不允许使用子线程(或者其它非创建控件的UI线程)去控制(这在NET2.0以下是允许的,但是考虑到安全性等问题,从2.0开始就禁止使用这个功能,除非Form的CheckForIllegalCrossThreadCalls=true,不推荐这样使用)。
那么如何实现C#窗体与子线程的交互呢?具体方法如下:
一、使用Invoke或者BeginInvoke方法:
用一个线程,里边调用Invoke或者BeginInvoke方法即可:
public partial class Form1 : Form{public void Processing(int num){int answer = 2;Task t = new Task(() =>{for (int i = 3; i <= num; i++){answer *= i;}this.BeginInvoke(new MethodInvoker(() => { Thread.Sleep(3000); MessageBox.Show("Finished!") }));MessageBox.Show("OK");});t.Start();}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){MessageBox.Show("First!");Processing(10);}}
这里值得注意:
1)BeginInvoke:这里的“异步”并不是针对UI线程,而是说当Control的BeginInvoke在某个子线程中调用时,子线程中BeginInvoke后面的代码(弹出“Finished”框框)会先执行,然后等到BeginInvoke中的那个委托方法完全执行完毕之后Label才会被赋值。如果改成Invoke,那么“OK”永远在Invoke的委托代码彻底执行完毕之后才被执行。
所以BeginInvoke=Invoke(在UI主线程中,所以不建议在主线程中直接这样调用)
二、线程同步SynchronizedContext:
public partial class Form1 : Form{public void Processing(int num,SynchronizationContext context){int answer = 2;Task t = new Task(() =>{for (int i = 3; i <= num; i++){answer *= i;}SynchronizationContext.SetSynchronizationContext(context);SynchronizationContext.Current.Post((obj) => { Thread.Sleep(3000); MessageBox.Show("Finished"); }, null);MessageBox.Show("Last");});t.Start();}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){MessageBox.Show("First!");Processing(10,SynchronizationContext.Current);}}
和BeginInvoke、Invoke类似,需要注意:
1)SynchronizationContext:唯独在UI窗体线程中会自动初始化(button1_Click事件中SynchronizationContext.Current为当前窗体),其它线程与线程要交互,必须通过new SynchronizationContext()实现)。
2)Post方法等同于BeginInvoke作用,Send等同于Invoke作用。
大家如果仔细实验代码,还会发现无论何种情况,弹出“Finished”框框总是界面“假死”3秒,是的,证明了以上4个方法都是在UI线程上执行的(只不过是同步或者异步向窗体消息泵发送信息而已)。所以应该“一次性地把数据在子线程中先全部处理干净(在Invoke,BeginInvoke,Send或者Post前得出结果,写代码),然后一次性发送通知给窗体,更新界面即可)。
此外还需要注意:
任何委托(Delegate)也有BeginInvoke方法,它是真正的异步,一旦Invoke一定是开辟一个线程去执行的。
边栏推荐
- 磁性层状双金属氢氧化物和酶-DNA复合物|聚乙烯亚胺-DNA复合物(PEI/DNA)|作用机理
- 探索创客教育在线管理实施体系
- 关于安装软件时x86 ,x64,x86_64,ARM 64, ARM 32 的选择
- Agile Organization | The path for enterprises to overcome the impact of the digital wave
- The ambition of glory: "high-end civilians" in a smart world
- Briefly talk about K-means clustering
- 一线技术人应该关注的四种思维能力
- LOG4J 学习
- 朴素贝叶斯“朴素”在哪里?
- 这半年我做交易链路自动化回归的那些事儿...
猜你喜欢

MSNs-SS-siRNA二氧化硅-二硫键-核酸RNA|HA-SS-siRNA,hyaluronic acid透明质酸修饰RNA(RNA修饰剂)

conda virtual environment | install and list problems

ds1302——Bin brother 51

R语言对airbnb数据nlp文本挖掘、地理、词云可视化、回归GAM模型、交叉验证分析

8.2实训任务 Sqoop的安装与配置

双功能RGD-TAT修饰DNA纳米胶束|聚苯胺纳米线修饰DNA(PAINW/DNA)

JSP Servlet JDBC MySQL CRUD 示例教程

RNA修饰技术介绍|介孔二氧化硅纳米颗粒(MSN)搭载的微小RNA-24(miR-24)纳米载体复合物

这半年我做交易链路自动化回归的那些事儿...

R language for airbnb data nlp text mining, geography, word cloud visualization, regression GAM model, cross-validation analysis
随机推荐
[mathematical foundation] higher mathematics concept learning
五个供应商销售谈判策略的识别以及应对它们的方法
siRNA-S-S-PEG-LMWP|M-MSN-siRNA介孔二氧化硅修饰RNA(齐岳RNA功能化修饰)
webUI测试框架设计思路详解
SAG1-MIC8复合DNA基因疫苗|新型脂质-HAP-DNA复合体|实验要求
ACM学习书籍简介
Samba服务器配置(什么情况下需要服务器)
LeetCode_474_ one and zero
offsetwidth111[通俗易懂]
conda虚拟环境 | install 与 list 问题
第二增长曲线 | 企业创新突破停滞困境的驱动指南
全排列的一点小技巧:康托展开
Hyaluronic acid-siRNA透明质酸修饰核糖核酸|peptide–siRNA 多肽偶连RNA/DNA核酸(齐岳PNA修饰物)
藻酸盐/PEI/DNA复合载体|脂质-鱼精蛋白-DNA复合物|合成方法
ES6用法,面试大全
朴素贝叶斯“朴素”在哪里?
regular expression
JUC并发编程基础AQS
百度实习学弟深夜吐槽:原来大厂是这种生活啊
ESP8266-Arduino programming example-EEPROM read and write