2013-10-29 106 views
5

我是線程和異步編程的新手。我正在嘗試學習這些概念,到目前爲止我理解它,但有一個問題需要問。線程vs begininvoke vs異步

假設我想調用一個名爲GetAllUsers()的方法,它需要很長時間才能執行,它不會阻塞資源並保持UI響應。所以,我的理解是,它可以用3種方式完成(請讓我知道,如果這些是正確的,或者我完全搞錯了): -

1)線程:我可以產生一個新線程並給GetAllUsers方法作爲threadstart。這將開始在另一個線程上執行該方法,以保持我的UI響應,並且當調用完成時,我可以使用路由技術來更新UI控件,即InvokeRequired。我的理解是否正確?

2)異步委託:我可以創建一個委託。創建一個新的實例並將其指向方法GetAllUsers。然後使用BeginInvoke方法。引擎蓋下的BeginInvoke會產生一個新的線程並運行我的方法來保持UI的響應。當調用完成時,將調用回調方法,並再次使用路由技術來更新GUI線程上的控件。我的理解是否正確?

或者

3)異步/等待:標記外的方法異步和標記調用方法GetAllUsers作爲AWAIT。這也將保持UI的響應,因爲正在運行的線程可以跳出並做一些其他工作,直到完成對這個緩慢方法的調用。我的理解是否正確?

現在,問題是 - 如果您閱讀下面鏈接的第二段,它說async/await不會導致創建額外的線程。那麼async/await如何管理與上面的第2個解決方案相同的輸出,而無需創建任何其他線程。解決方案1和2將導致多線程,但異步解決方案不會。異步/等待如何在引擎蓋下工作?

http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads

回答

8

是我的理解是否正確?

是的,你的理解是正確的。

現在,問題是 - 如果您閱讀下面鏈接的第二段,它說async/await不會導致創建其他線程。那麼,如何異步/ AWAIT設法給輸出作爲第一2solution同上不會造成任何額外的線程

async改性劑和await運營商做不一定創建新的線程。執行異步的實際機制由您稱之爲await的類型處理。如果使用await Task.Run(() => YourMethod());,那麼Task.Run確實使用線程池線程來執行操作。

但是,如果您可以修改方法以便GetAllUsers使用異步IO調用而不是線程,那麼await將不需要使用線程異步。例如,如果GetAllUsers大部分時間都在等待從服務器下載,則使用異步Web API將允許您在不使用額外線程的情況下使該方法異步。

在這種情況下,即使你有使用Task.Runawait,這裏有一個很好的優勢 - 你可以返工你的方法使用await,並不會弄亂其邏輯控制流程,保持異常處理乾淨,而不必擔心使用BeginInvoke推回UI線程 - 與await,所有的「混亂」處理你,你的代碼可以保持非常接近原始的非異步代碼。

+2

Hrm ...爲什麼在這裏downvoting? –