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的第六行一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM