跨线程访问控件的问题和编程方法

很多时候写windows程序都需要结合多线程,经常会跨线程操作控件,这时就会出错,提示不允许"从不是创建控件的进程访问它"。

这个时候的解决思路:把想对另一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数,并且在那个函数中加入一个判断,用InvokeRequired来判断调用这个函数的线程是否和控件线程在同一线程中,如果是则直接执行对控件的操作,否则利用控件的Invoke或BeginInvoke方法来执行这个代理,执行唤醒控件的操作。
Invoke的中文解释是唤醒,它有两种参数类型 (Delegate, Object[])和(Delegate)
Delegate就是前面提到的那个代理,而Object[]则是用来存放Delegate所代理函数的参数

delegate void aa();//定义代理

private void CtlInvoke()
{
    if (label1.InvokeRequired)//判断是否需要唤醒操作(当前线程与控件是否属于一个线程,否就执行唤醒,是就执行方法)
    {
        aa a1 = new aa(label1);//执行代理
        label1.Invoke(a1);//执行唤醒操作
    }
    else
    {
        return;
    }
}

时间: 2024-11-18 09:10:42

跨线程访问控件的问题和编程方法的相关文章

c#使用MethodInvoker解决跨线程访问控件

功能函数测试集锦(77)  C#专区(114)  版权声明:本文为博主原创文章,未经博主允许不得转载. .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线程访问作检查,Control.CheckForIllegalCrossThreadCalls = false;可以实现访问,但是出不出错不敢保证C#跨线程访问控件运行时错误. 使用MethodInvoker即可解决: 原代码: private void btnOK_Click(object sender

2 跨线程访问控件InvokeHelper类

这里是一张动画,演示在多线程(无限循环+Thread.Sleep)情况下主界面操作不受影响. 多线程是一种提高程序运行效率和性能的常用技术.随着我们学习工作的深入,在编程中或多或少会涉及到需要多线程的情况.多数时候,我们的操作模式是后台线程中处理数据,计算结果,然后在前台界面(GUI)中更新显示. 在.NET Framework中,为了保证线程安全,避免出现访问竞争等问题,是不允许跨线程访问窗体控件的.如果强行访问,则会引发InvalidOperationException无效操作异常,如下图:

C# WinFrom 跨线程访问控件

1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summary> /// 跨线程访问控件的委托 /// </summary> public delegate void InvokeDelegate(); /// <summary> /// 跨线程访问控件类 /// </summary> public class Invok

WinForm跨线程访问控件异常

WinForm跨线程访问控件异常 最近做了个WinForm的小项目,遇到个简单的问题记录下.需求:点击"下载",显示正在下载,下载完后更新状态为"ready"(要求用多线程,避免前台卡死). 做法 新建一个线程,在新线程中下在更新控件状态,报异常跨线程程访问控件(当然可以通过关闭跨线程访问控件检验解决,不鼓励这么做).应该C#5.0版本添加的任务Task异步,这里用异步解决. Code 新建WinForm 项目,Form1添加控件如图 后台代码 private vo

C#之Winform跨线程访问控件

C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用new MethodInvoker(LoadGlobalImage)来完成下面的步骤,这个做法保证了控件的安全,你可以这样理解,有人想找你借钱,他可以直接在你的钱包中拿,这样太不安全,因此必须让别人先要告诉你,你再从自己的钱包把钱拿出来借给别人,这样就安全了 ----------------------

跨线程访问控件的方法

主窗体创建的控件相当于主线程管理,在分线程使用的时候会产生跨线程访问的问题,这时需要如下判断写法,即可解决 if (lblNum2.InvokeRequired) { lblNum2.Invoke(new Action<string>(s => { this.lblNum2.Text = s; }), Thread.CurrentThread.ManagedThreadId.ToString()); } else { this.lblNum2.Text = Guid.NewGuid().

Winform之跨线程访问控件(在进度条上显示字体)

此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理  有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将xml文件导入sqlite数据库   每个xml有将近3000的节点  每个节点有5个属性,如果我们不用线程那么在数据导入的过程中   程序很可能卡死   而且基本上动不了,用户的体验性就很差. 所以我们对向数据库添加数据的地方使用了线程: Thread thread = new Thread(new

跨线程访问控件解决办法

在多线程中访问控件有两种方式 方式1: 取消对跨线程操作的检查 在 from 的构造 函数中增加 system.window.forms.control.CheckForIllegalCrossThreadCalls=false; 方式2 : 采用委托的形式作为代理通知主线程控件,允许访问. delegate void   showData(string para); visistControl(string para) { if (this.textbox1.invokeRequered) /

C#WinForm解决跨线程访问控件属性报错

方式一(在程序初始化构造函数中加一行代码): 1 public Form1() 2 { 3 InitializeComponent(); 4 Control.CheckForIllegalCrossThreadCalls = false; //设置不捕获线程异常 5 } 方式二(推荐): 1 private void btnLoop_Click(object sender, EventArgs e) 2 { 3 Thread thread = new Thread(()=> { 4 while