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

最近在一个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的第六行一样。

posted @ 2016-08-03 11:21  小码戈  阅读(1744)  评论(0编辑  收藏  举报