分享

C# 跨线程访问及修改控件属性

 思羽哥哥 2018-06-17

在数据接收线程中,当接收到数据并且校验正确后,我怎么显示这些数据到窗体中呢?要显示数据,必须要访问主线程(A)的各种控件,而数据接收是另一个线程(B)。有两种方案可以解决这个问题,和上文一样,也是第二个较好。

方法一:取消跨线程操作检查

当线程B在访问线程A创建的控件时,线程A会对控件的线程锁进行检验,当多个线程同时对控件进行写操作时,必然产生冲突,因此此时的程序会非常不稳定,经常突然就退出,Debug显示原因是跨线程操作控件了。既然如此,那就让线程A不去检验其他线程了,

在Form_Load函数里加一句:

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

就万事大吉了。很显然,这种方法不推荐使用。

 

方法二:使用代理机制

原理:有一个代理D,他负责沟通主线程A和其他线程B,当是主线程操作控件时,正常执行;当是其他线程B操作控件时,通知代理D,之后代理D唤醒主线程A,告诉主线程A去更改控件的一些属性,显然,这样一来,就不存在跨线程操作了,所有的任务由代理D来完成。示例代码如下:

使用delegate定义一个代理DelShow。在其他线程中访问控件textbox1时,直接调用showData('其他线程');就可以了,showData函数能自动区分是否是主线程。

delegate void DelShow(String Msg); //代理
//将对控件的操作写到一个函数中
private void showData(String para) {
if (!textbox1.InvokeRequired) //不需要唤醒,就是创建控件的线程
//如果是创建控件的线程,直接正常操作
{
textbox1.Text
= para;
}
else //非创建线程,用代理进行操作
{
DelShowds
= new DelShow(showData);
//唤醒主线程,可以传递参数,也可以为null,即不传参数
Invoke(ds, new object[]{para});
}
}
showData('其他线程');

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多