C#跨线程操作控件

问题:
在WinForm中使用多线程时,常常遇到一个问题,当在子线程(非UI线程)中修改一个控件的值:比如修改进度条进度,时会抛出如下错误

Cross-thread operation not valid: Control ‘XXX’ accessed from a thread other than the thread it was created on.

在VS2005或者更高版本中,只要不是在控件的创建线程(一般就是指UI主线程)上访问控件的属性就会抛出这个错误,解决方法就是利用控件提供的Invoke和BeginInvoke把调用封送回UI线程,也就是让控件属性修改在UI线程上执行

解决:

delegate void Mydelegate(object adress);

if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate { ChangeData(adress); }));
//this.BeginInvoke(new Mydelegate(ChangeData),adress);
}
else

{
ChangData(adress);
}

关键在于if分支里的语句,首先this.InvokeRequired是控件的一个属性,它表示调用是否来自非UI线程

所以如果来自非UI线程,则需要使用控件的Invoke()或者BeginInvoke()方法来执行,其中一个是同步,一个是异步后面会仔细说两个的区别。

Invoke方法需要传入一个委托例如第一行:this.Invoke(new MethodInvoker(delegate { ChangeData(adress); }));其中MethodInvoker是.net类库里定义的表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法。(MSDN)delegate { ChangeData(adress); }是简洁的写法,表示传入一个参数的委托。相当于:

public delegate void Mydelegate(object adress);

Mydelegate delegate = new Mydelegate(ChangeData);

public void ChangeData(object adress)

{

}

所以通过Invoke方法可以同步的将要执行的方法(ChangeData)在UI线程上执行

BeginInvoke与Invoke方法签名相同this.BeginInvoke(new Mydelegate(ChangeData),adress);注意这里传参用了和上面不同的方式,其实这两种方式在BeginInvoke与Invoke方法都可以使用

第一个参数是一个委托new Mydelegate(ChangeData)也就是在上面定义的

delegate void Mydelegate(object adress);的实现,第二个参数是要传入的参数,可以是一个对象数组

前面多次提到BeginInvoke与Invoke一个是同步执行,一个是异步执行。

简单的可以理解为,当使用Invoke时,当前线程(非UI线程)会阻塞然后UI线程执行Invoke里传入的方法,之后再继续执行当前线程。

而使用BeginInvoke时,当前线程不会阻塞,而是继续执行,当当前线程执行完毕后,UI线程才会执行BeginInvoke传入的方法。

Invoke使用了Win32API的SendMessage,

UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);

BeginInvoke使用了Win32API的PostMessage

UnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);

转自:http://blog.sina.com.cn/s/blog_1499e59430102vkfp.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值