标签:
最近在一个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()的区别
标签:
原文地址:http://www.cnblogs.com/small-code/p/5732116.html