await與async語法糖

今天說一個簡單的知識點,在.net core會經常碰到。

await/async

這是一個語法糖,之所以說它時語法糖是因為微軟在設計這個語法時,沒有對CLR進行改造,C#版本升級到5.0才出現的,跟C#支持泛型不是同一個級別。

它有以下幾個特點:

  1. 任何一個方法都可以增加async
  2. await和async是成對出現,只有async是沒有意義的,只有await會報錯
  3. await只能放在Task前面

來看看之前沒有async的代碼

await與async語法糖

運行結果:

await與async語法糖

我們發現主線程一如既往的執行,連InnterCodeA方法裡面的

await與async語法糖

都是主線程執行的,當遇到Task.Run()的時候,只是負責開闢一個新的線程去執行代碼,沒有涉及到誰等誰的問題。

如果用到await/async就不同了,看代碼:

await與async語法糖

運行結果如下:

await與async語法糖

現在我們發現代碼類似回調的表現了,當遇到await的時候,返回主線程,同時開闢的新線程繼續執行代碼,當新線程執行完畢代碼後立刻輸出。注意InnterCodeB方法裡的

await與async語法糖

執行時間,它是在新線程執行後才執行的,它好像就在“等”新線程執行完畢似的。我個人感覺這裡就是await/async最大價值的體現,讓原本異步混亂的代碼執行有了順序,讓人感覺它好像是在同步執行,讓代碼更加直觀可控。如果你還感覺迷茫,看下面多個await的代碼。

具有返回值的await/async

await與async語法糖

代碼執行結果:

await與async語法糖

當新開闢的線程執行完後,繼續向下執行,又碰到await繼續等待執行,完全是在同步執行代碼。在這裡主線程也在等待是因為

await與async語法糖

其中的t.Result,它相當於t.Wait();方法,等待所有的線程執行完才執行下面的代碼。不過這裡的重點是InnterCodeC方法裡面兩個await執行的順序。

綜上所述,內部實現的原理就是基於狀態模式,在新開闢的線程當作一個又一個的狀態,當前狀態發生變化時,轉移到下一個狀態,執行代碼,依次進行下去。


分享到:


相關文章: