C#在一个线程中操作另一个线程的控件

C#在一个线程中操作另一个线程的控件
本文摘自:拾金者(http://www.xkde.com) 详细出处参考:http://www.xkde.com/ComContent-149-7466.aspx

默认情况下,C#不允许在一个线程中直接操作另一个线程中的控件,这是因为访问windows窗体控件本质上不是线程安全的.如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态.还可能出现其他线程相关的BUG,以及不同线程争用控件引起的死锁问题.因些确保以线程安全方式访问控件非常重要.

 

在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个InvalidOperationException异常,并提示消息:从不是创建控件的线程访问它.

但是在windows应用程序中,为了在窗体上显示线程中处理的信息,我们可能需要经常在一个线程中引用另一个线程的窗体控件.比较常用的办法是使用委托(delegate)来完成这个工作.

为了区别是否是创建控件的线程访问该控件,windows应用程序中每一个控件对象都有一个InvokeRequired属性,用来检查是否需要通过调用Invoke方法完成其他线程对该控件的操作,如果该属性为true.说明是其他线程操作该控件,这时可以创建一个委托实例,然后调用控件对象的Invoke方法,并传入需要的参数完成相应操作,否则可以直接对该控件对象进行操作,从而保证了其他线程安全操作本线程中的控件.

例如:

 

以下是引用片段:
Delegate void AppendStringDelegate(string str);
Private void AppendString(string str)
{
If(richTexBox1.InvokeRequired)
{
AppendStringDelegate d=new AppendStringDelgate(AppendString);
richTexBox1.Invoke(d,”abc”);
}
Else
{
richTextBox1.Text+=str;
}
}
上述这段代码中,首先判断是否需要通过委托调用对richTexBox1的操作,如果需要,则创建一个委托实例,并传入需要的参数完成else代码块的功能,否则直接执行else代码块中的内容.

     实际上,由于我们在编写程序时就已经知道控件是在哪个线程中创建的.因此也可以在不是创建控件的线程中直接调用控件对象的Invoke方法完成对其他线程中的控件的操作.

 

注意:不论是否判断InvokeRequired属性,委托中参数中的个数和类型必须与传递给委托的方法需要的参数个数和类型完相相同.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值