Control的Invoke和BeginInvoke

参考资料:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.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。我就不再过多描述了!

posted @ 2013-06-16 00:35  LS庆  阅读(492)  评论(0编辑  收藏  举报