您的位置:首页 > 其它

Control的Invoke和BeginInvoke

2013-06-16 00:35 302 查看
参考资料:/article/5975999.html

http://www.cnblogs.com/c2303191/articles/826571.html

在多线程操作WinForm窗体上的控件时,需要使用Control的Invoke方法或BeginInvoke方法。Control的Invoke方法和BeginInvoke方法传递一个委托对象作为参数,它们的作用都是将它们的委托对象(也可以说是该委托对象的方法)交给UI线程去处理。为什么?因为另一个线程操作窗体上的控件时,会和UI线程(即主线程)产生竞争,造成不可预料的结果,甚至死锁。所以windows GUI编程有一个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产生不可预料的结果。通俗点的说就是对控件的操作,只能在创建这个控件的线程中执行,否则无效!你是否记得在多线程上改变窗体上的控件时,出现的“线程间操作无效:从不是创建控件的XXX的线程访问它”报错提示?讲的就是这个原因。

那么Invoke和BeginInvoke又有什么差别?—对于调用Invoke的线程,在Invoke的方法返回前,这个线程会阻塞;对于调用BeginInvoke的线程,在BeginInvoke的方法返回前,这个线程不会阻塞!

// 声明委托类型
delegate void ShowMsgInTextBoxDelegate(string msg);
// 创建委托对象,用于安全地将服务端发送过来的消息显示到文本框中
ShowMsgInTextBoxDelegate showMsgInTextBox = new ShowMsgInTextBoxDelegate(ShowMsgByDelegate);
// 通过委托安全地将消息显示到文本框中
void ShowMsgByDelegate(string msg)
{
if (showMsgInTextBox != null)
{
// this是Form窗体对象
if (this.InvokeRequired)   // 判断调用Invoke的线程是否和控件是属于同一线程(判断是否跨线程访问控件)
{
this.Invoke(showMsgInTextBox, msg);   // 或this.BeginInvoke(showMsgInTextBox, msg);
}
else
{
txtMsg.AppendText(msg + "\r\n");
}
}
}


具体更加详细的示例可以看看:http://www.cnblogs.com/c2303191/articles/826571.html。我就不再过多描述了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: