我想前言這個問題有以下幾點:在TPL下啓動阻塞I/O請求的線程如何立即返回?
我熟悉的
IAsyncStateMachine
實施,在C#中的關鍵字await
產生。我的問題是不是能夠確保當您使用
async
和await
關鍵字控制的基本流程。
假設一個
在任何線程環境的默認線程行爲,無論是在Windows操作系統級別或POSIX系統或.NET線程池,一直認爲當線程發出請求進行I/O綁定操作,例如對於磁盤讀取,它向磁盤設備驅動程序發出請求,並且進入等待狀態。當然,我在細節上留言,因爲它們不是我們討論的時刻。
重要的是,該線程只能通過設備驅動程序的中斷來解除阻塞,直到它通知完成。在此期間,線程保持在等待隊列上,並且不能重新用於其他任何工作。
我首先想要確認上面的描述。
假設乙
其次,即使引進第三方物流,其增強在.NET框架V4.5完成,並與涉及任務異步操作語言層面的支持,這種默認行爲描述於假設A尚未更改。
問題
然後,我不知所措試圖調和假設A和B與要求突然在所有TPL文獻中出現了:
當,說,主線程啓動這個請求,爲這個I/O綁定的 工作,它立即返回並繼續執行消息泵中排隊的消息的其餘部分 。
那麼,是什麼讓那個線程返回回去做其他工作?是不是該線程應該在等待狀態等待隊列?
您可能會試圖回覆狀態機中的代碼啓動任務awaiter,並且如果awaiter尚未完成,主線程將返回。
乞丐的問題 - 請求者運行什麼線程?
而引發思考的答案是:無論該方法的實施情況如何,其任務等待的是誰的任務。
這會讓我們更加深入兔子洞,直到我們到達實際提供I/O請求的最後一個實現。
.NET框架中的那部分源代碼在哪裏改變了關於線程如何工作的基礎機制?
旁註
雖然有些堵異步方法,如
WebClient.DownloadDataTaskAsync
,如果一個人通過遵循他們的代碼 他們(該方法的,而不是自己)橢圓形道到他們 腸,一會看到他們最終要麼同步執行 下載,如果請求同步執行 (Task.RunSynchronously()
)或者如果異步請求,則阻止當前線程 offloa d阻塞I/O使用 異步編程模型(APM)Begin
和End
方法綁定調用線程池線程。這無疑將導致主線程立即因爲 它只是卸載阻塞I/O工作返回線程池線程,從而 增加約diddlysquat應用程序的可擴展性。
但是這是一個案例,在獸的腸內,工作 被祕密卸載到線程池線程。在API 不這樣做的情況下,說看起來像這樣的API:
public async Task<string> GetDataAsync() { var tcs = new TaskCompletionSource<string>(); // If GetDataInternalAsync makes the network request // on the same thread as the calling thread, it will block, right? // How then do they claim that the thread will return immediately? // If you look inside the state machine, it just asks the TaskAwaiter // if it completed the task, and if it hasn't it registers a continuation // and comes back. But that implies that the awaiter is on another thread // and that thread is happily sleeping until it gets a kick in the butt // from a wait handle, right? // So, the only way would be to delegate the making of the request // to a thread pool thread, in which case, we have not really improved // scalability but only improved responsiveness of the main/UI thread var s = await GetDataInternalAsync(); tcs.SetResult(s); // omitting SetException and // cancellation for the sake of brevity return tcs.Task; }
如果我的問題似乎是荒謬請溫柔的我。幾乎所有事情的事物知識程度都是有限的。我只是在學習任何東西。
我認爲bodangly的工作做得很好,但爲了完整起見,這裏有一個鏈接到[POSIX Async IO]的手冊頁(http://man7.org/linux/man-pages/man7/aio.7。 html)(在Linux內),再次證明假設A是如何破解的。 –
@Damien_The_Unbeliever哇!謝謝。那爲我做了。 –
也看到我的答案在這裏:http://stackoverflow.com/questions/37419572/if-async-await-doesnt-create-any-additional-threads-then-how-does-it-make-appl/37419845#37419845 –