跨线程直接调用控件在C#中是不被允许的。因为会有安全问题,如下:
.
///主函数省略
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) //线程执行函数
{
label1.Text ="666";//lable1显示为666
}
private void button1_Click(object sender, EventArgs e) 按键按下事件
{
backgroundWorker1.RunWorkerAsync(); //线程执行命令
}
以上点击按键使线程backgroundWorker1执行,这肯定会报错,我们平时会用到跨线程调用问题,那么我将说两种方案
方案一 :不严谨方案,用于简单的时候
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false; //禁用线程检测
}
禁用线程检查,这样就解决了报错问题,所谓的出现问题,解决提出问题的人,问题就解决了。。但是这样存在风险,毕竟问题还是存在,在复杂系统中会出现迷之不报错的错误,会让你更加蒙蔽,所以仅在不需要特别严谨的时候使用,方便快捷
方案二:跨线程委托事件
private delegate void book();//申明委托量
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BeginInvoke(new book(pp)); //线程内执行委托事件
}
void pp () //被委托的函数
{
label1.Text ="666"; //要执行的事件内部
}
private void button1_Click(object sender, EventArgs e) //按键事件
{
backgroundWorker1.RunWorkerAsync(); //执行线程
}
这样使用委托事件,在按键按下,线程1执行时,线程内部通过委托事件,让主线程执行函数
void pp(); 就能够更加完美的解决委托问题。
如果你委托函数存在参数传递可以通过全局变量来传递,但是为了安全,我们也可以使用以下类似方法:
private delegate void book( int c);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int value=20;
BeginInvoke(new book(pp),value);
}
void pp (int c )
{
label1.Text = c.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
这样label1显示的是20 ,同样多个参数 也同理
新方法
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
sock.Receive(p);
this.Invoke((EventHandler)delegate
{
richTextBox1.Text = System.Text.Encoding.UTF8.GetString(p);
p = new byte[50];
});
}
}