深入理解Async/Await
C# 5?Async/Await?語法特性,極大地簡化了異步編程,但我們知道,異步編程的基本原理并沒有發生根本改變。也就是說,當一些復雜的東西看起來很簡單時,它通常意味著有一些有趣的事情在背后發生。在計算機程序設計語言領域,我們把這些本身很復雜但看起來很簡單的語言特性稱為語法糖,通常情況下,我們并不需要深入理解語法糖是怎么被一層一層包裹起來的,但是,最近我在使用.NET Core實現MySQL協議過程中,需要實現一個Awaitable Socket,所以我需要知道Async/Await背后到底發上了什么?
編譯器重寫
我們通過寫一個非常簡單的控制臺應用程序,一層一層地剝開C#編譯器實現的?Async/Await?語法糖。
namespace AsyncAwaitInDepth{class Program{static void Main(string[] args){ }static async int Method(){return 1;}}}編譯上面的C#代碼,會出現CS1983 The return type of an async method must be void, Task or Task<T>錯誤,即編譯器告訴我們,異步方法僅限于三個不同的返回類型︰
void
Task
Task
再修改一下代碼,讓編譯器編譯通過:
? ??}}
使用ILSpy或者Reflector看看編譯器干了什么:
上面的代碼可以發現,aynce/await?代碼被C#編譯器重寫了,編譯器通過使用三個Builder和動態生成的StateMachine替換掉了我們的代碼,而把我們的代碼整理到StateMachine的MoveNext()方法內部,三個Builder是:
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
撇開這三個Builder的內部實現,從接口角度看,他們長得很像,我們只看看AsyncTaskMethodBuilder<T>接口:l
C#編譯器動態生成的StateMachine實現了IAsyncStateMachine接口:
AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder
我們自己代碼中的await Task.Delay(5);表達式,在StateMachine的MoveNext()方法內部被替換成awaiter = Task.Delay(5).GetAwaiter();,然后通過IsCompleted屬性判斷是否需要啟動一個新的線程去執行,最后通過awaiter.GetResult();獲取結果,或者是給Builder設置異常builder.SetException(exception);
Awaitables and Awaiters
在.NET中,我們知道Xtable和Xter是一個一對的概念,比如IEnumerable<T>和IEnumerator<T>,上面的代碼,我們發現Task,Task<TResult>是可以被awaited的,他們是awaitable,可以通過其GetAwaiter()方法得到awaiter:
awaitable的GetAwaiter()可以是實例方法,也可以是擴展方法。該方法返回的是一個awaiter,該awaiter必須實現INotifyCompletion接口,可選實現ICriticalNotifyCompletion接口,同時,必須提供一個名為IsCompleted?bool?屬性, 必須提供public TResult GetResult()方法。
自定義awaitable和awaiter對象
我們費了那么大的勁,終于弄清楚了?Async/Await?背后到底發上了什么,做到了知其然知其所以然,因此,我們可以實現自己的awaitable和awaiter對象:
最后,借用《C# in Depth》作者Job Skeet的一句話與大家共勉:
I like knowing how a feature works before I go too far using it
我們團隊正在招聘幾個小伙伴【招聘】騰訊(深圳)新增招聘互聯網金融.NET開發,我們是有追求的團隊,不滿足CRUD,我們探索.NET的深度技術,不僅僅是完成業務,我們追求極致,如果你也是這樣,歡迎加入我們。
原文地址:http://www.xyting.org/2017/02/28/understand-async-await-in-depth.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
贊賞
人贊賞
總結
以上是生活随笔為你收集整理的深入理解Async/Await的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Azure SQL的DTU和eDTU到底
- 下一篇: 【南京】.Net 开源基础服务线下技术交