首页 > 其他 > 详细

Control.BeginInvoke()和delegate的BeginInvoke()的区别

时间:2019-10-11 12:39:46      阅读:63      评论:0      收藏:0      [点我收藏+]

最近在一个demo中了解到可以用BeginInvoke来处理异步,于是我也自己做了一个winform来学习BeginInvoke。

在窗体上放置了一个按钮和一个label,点击按钮3秒后再label上显示“Hello World”。先是有了如下代码:

技术分享图片
 1         private void btnStart_Click(object sender, EventArgs e)
 2         {
 3             BeginInvoke(new xDel(k =>
 4             {
 5                 Thread.Sleep(k);
 6                 txtMain.Text = "Hello World";
 7             }), 3000);
 8         }
 9 
10         delegate void xDel(int i);
技术分享图片

 

点击按钮后调用BeginInvoke执行异步,传递一个委托。按照我的设想,应该BeginInvoke应该是创建一个新线程执行委托,所以不会造成UI假死。

但是结果是运行后UI还是假死了。

 

后来上网查找了一些资料才发现,原先看的demo里使用的委托的BeginInvoke方法,而我写的BeginInvoke是属于Control类的。正确的写法应该是:

技术分享图片
 1  private void btnStart_Click(object sender, EventArgs e)
 2         {
 3             xDel xd = new xDel(t =>
 4             {
 5                 Thread.Sleep(t);
 6                 BeginInvoke(new Action(() =>
 7                 {
 8                     txtMain.Text = "Hello World";
 9                 }));
10             });
11             xd.BeginInvoke(3000, null, null);
12         }
13 
14         delegate void xDel(int i);
技术分享图片

 

这两者的区别在于委托的BeginInvoke方法是新起一个线程来执行委托,而原线程继续往下执行;Control.BeginInvoke则是将委托强制传递至UI线程执行,所以可能会造成UI线程假死。

所以想要执行异步,应该用delegate的BeginInvoke方法;而Control.BeginInvoke方法主要用途是让子线程可以跨线程操作UI线程的控件,正如代码2的第六行一样。

Control.BeginInvoke()和delegate的BeginInvoke()的区别

原文:https://www.cnblogs.com/wwwbdabc/p/11653060.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!