2013-05-01 102 views

回答

5

這是async最基本的真相:沒有線程。

對於一個真正的異步流,ReadToEndAsync幾乎沒有工作要做。當您調用該方法時,它只會要求運行時讀取到最後,並在操作完成時通知它(通過Task)。運行時轉向操作系統,要求它讀取並在操作完成時通知它(例如,通過IOCP)。操作系統轉向設備驅動程序,要求它讀取,並在操作完成時通知它(例如,通過IRP)。設備驅動程序轉向設備,要求它讀取,並在操作完成時通知它(例如,通過IRQ)。

沒有線程。

當然,這是理想的情況。在現實世界中,在某些時候,「讀取到結束」操作被分解成幾個「讀取n字節」操作,並且這些操作需要被一起縫合。使用借用的線程完成這個(微小的)工作量:用於內核模式代碼的不可知線程和用於用戶模式代碼的線程池線程。

另外,在某些情況下,異步API不存在。在這些情況下,異步工作是使用線程池線程僞造的。例如,如果您在MemoryStream上調用ReadToEndAsync,則沒有用於從內存中讀取的異步API,因此這是一個將在線程池上運行的假異步操作。

但是總是必須有一個線程來執行異步操作的想法並不是事實。不要試圖控制線程 - 這是不可能的。相反,只有嘗試實現真相:沒有線程。

編輯:擴大答覆into a blog post

+0

謝謝Neo ...我的意思是斯蒂芬。糾正我,如果我錯了,所以這意味着無論這個過程需要多長時間,它都不會影響UI線程,因爲工作是在OS級完成的。但是當工作完成時,await語句下的代碼將在UI線程/上下文中執行回來? – ademartini 2013-05-01 21:04:32

+0

是的。在這種情況下,'await'後面的代碼將自動返回到UI線程。我在[我的異步/等待介紹](http://blog.stephencleary.com/2012/02/async-and-await.html)中更精確地解釋了這一點。 – 2013-05-01 21:17:36