1. 程式人生 > WINDOWS開發 >C#中的非同步

C#中的非同步

什麼是非同步?

作為一名Web端的碼農,第一次接觸非同步是Ajax。

非同步請求後端獲取資料來源,js操作html的dom節點,而無需要渲染整個網頁的操作。

頁面上點選按鈕,載入進度動畫,同時發起Ajax請求資料來源,使用者觀看載入動畫。在拿到資料後,中止動畫,開始渲染資料。使用者可以檢視到資料內容。

動畫渲染和請求資料兩個任務,同時進行,就是非同步。

什麼是非同步程式設計?

一個函式內做2件或者幾件事。(例如:點選按鈕載入動畫的同時處理資料。)

很多同學有疑問,一個函式內做2件或者幾件事,不就是多執行緒程式設計麼。怎麼又出來個非同步程式設計的名詞?

我們來看程式碼:

技術分享圖片

主執行緒會建立一個新的執行緒t,新的執行緒重複輸出B。同時,主執行緒也會重複的輸出A。但是可以發現在控制檯,輸出的A和B不是連續的,這是由於執行緒是搶佔式

的,它的執行和其它執行緒的程式碼是交錯執行的。

C#非同步程式設計的基礎型別是 Task,通過關鍵字 asyncawait 來快速實現。(早年還有APM、EAP)

task 單詞翻譯是任務,是Framework 4.0 時,作為並行程式設計庫的組成部分引入的。相比較 Thread 執行緒,任務的概念是個更高階的抽象概念。它代表一個併發操作,但是本身又不操作執行緒,也不一定依賴執行緒來完成。

比如:執行緒就像一個個快遞員,執行緒池就是快遞公司。任務,就是自己把想要的東西打包起來,交給快遞公司,讓快遞公司去處理,交給快遞員去運輸。

Task 預設使用執行緒池中的執行緒,它們都是後臺執行緒。意味著當主執行緒結束時,所有的任務也會隨之終止。

技術分享圖片

在如上圖的程式碼中,利用 Task.Run 運行了一個Task,但是控制檯並沒有列印。

技術分享圖片

新增Console.ReadLine(); 避免主執行緒結束,就會執行 Task 。要想 Task 順利完成,就要想辦法避免主執行緒的結束,Task 開啟後可以返回一個物件,可以用 Wait 等待

Task 還沒進行完的時候,告訴主執行緒,“嘿,老兄,我還沒好”。

技術分享圖片

Task 物件還有很多屬性,這裡就不介紹了。

要想編寫非同步函式,可將返回型別由 void 更改為 Task,如有返回值,Task<T>。

技術分享圖片

Task.Delay(1000);等待1000毫秒後再執行。

等待1秒後,輸出1000個A,再等待1秒後,輸出1000個B。然後結束主執行緒,退出當前程式。

這樣就不會出現多執行緒執行當中的交錯執行和相互搶佔。

參考資料《C# 7.0 核心技術指南