首页 > 代码库 > 多线程总结之旅(112):跨线程调用控件的几种方式
多线程总结之旅(112):跨线程调用控件的几种方式
本来是写完线程池就结束多线程总结之旅系列的,但是想想平时在项目中用到线程仅仅不够的,为什么这么说呢?举个例子:我们有一个函数,它的功能就是加载数据,然后绑定到datagridview。现在我们开启一个线程去执行这个函数。结果可想而知,它会报错:提示线程无法访问。。。之类的话。为什么报错呢?因为你在开启的线程中操作了datagridview控件,也就是你跨线程调用控件了。
那么我们应该怎么跨线程调用控件呢?下面我就把我总结的几种方法奉献给各位。
跨线程调用控件的几种方法:
1、方法一:Control.CheckForIllegalCrossThreadCalls = false;这是通过禁止编译器检查对跨线程访问操作,但是这种方法不是安全的解决办法,尽量不要使用。
为什么说不安全呢?
(1)我们查看CheckForIllegalCrossThreadCalls 这个属性的定义,就会发现它是一个static的,也就是说无论我们在项目的什么地方修改了这个值,他就会在全局起作用。
(2)一般对于跨线程访问是否存在异常,我们通常都会去检查。如果项目中其他人修改了这个属性,那么我们的方案就失败了。
代码下载:
2、方法二: 使用Delegate和Invoke跨线程调用控件(也叫代理方式)
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(ModifyLabelText); t.Start(); } /// <summary> /// 定义委托 /// </summary> private delegate void InvokeDelegate(); /// <summary> /// this.label1.InvokeRequired就是问问我们要不要使用代理执行ModifyLabelText方法 /// </summary> private void ModifyLabelText() { //使用Invoke代理的方式调用ModifyLabelText方法 if (this.label1.InvokeRequired) { InvokeDelegate invokeDelegate=new InvokeDelegate(ModifyLabelText); this.Invoke(invokeDelegate); } else { this.label1.Text = "我已经跨线程修改了Label的值"; } } }}
3、方法三:使用BeginInvoke和Delegate的方式。(也叫代理方式)
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace WindowsFormsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(ModifyLabelText); t.Start(); } /// <summary> /// 定义委托 /// </summary> private delegate void InvokeDelegate(); /// <summary> /// this.label1.InvokeRequired就是问问我们要不要使用代理执行ModifyLabelText方法 /// </summary> private void ModifyLabelText() { //使用BeginInvoke代理的方式调用ModifyLabelText方法 if (this.label1.InvokeRequired) { InvokeDelegate invokeDelegate=new InvokeDelegate(ModifyLabelText); this.BeginInvoke(invokeDelegate); } else { this.label1.Text = "我已经跨线程修改了Label的值"; } } }}
在这里进行一下说明:
多线程总结之旅(112):跨线程调用控件的几种方式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。