C#異步編程async/await


總結

async/await使C#用以實現協程編程的方式,由Task調度器統一調度每一個異步任務的執行,從調度器的線程池中拿出線程來執行,遇到await時線程會被回收,直到異步方法執行完成

async本身沒有任何實際作用,只是在編碼期給程序員提示調用的方法為異步,真正起作用的是await和Task實例,await遇到Task實例便會將當前線程異步等待,直到執行Task實例的線程結束

主線程執行到await后便停止,不再繼續執行后續代碼,直到輔線程執行完await發起的異步任務

同時發起多個異步任務

把Task實例保存在一個數組中,用await Task.WhenAll(taskArray)等待所有異步任務結束,不可每個任務單獨使用一個await

參考:

自定義異步方法

方法標記為async,用await發起一個Task實例,在Task實例中定義要異步執行的任務

創建Task實例的簡便方式是用Task.Run靜態方法,入參是任務的lambda表達式

private async Task<string> SetSysBatchId(string traceCode)
{
    return await Task.Run(() =>
    {
        return SecurityHelper.md5(traceCode);
    });
}

網上資源摘要

鏈接:

如果沒有使用await關鍵字,那么該方法就作為一個同步方法。編譯器將向我們顯示警告,但不會顯示任何錯誤。

async/await本質上只是一個語法糖,它並不產生線程,只是在編譯時把語句的執行邏輯改了,相當於過去我們用callback,這里編譯器幫你做了

async並不是表明這個方法是異步方法,而是表明這個方法里有異步調用,真正重要的是await,他會同步等待異步調用的完成

async 和 await 關鍵字不會創建其他線程。因為異步方法不會在其自身線程上運行,因此它不需要多線程。

如果使用 async 修飾符將某種方法指定為異步方法,即啟用以下兩種功能。

  1. 標記的異步方法可以使用 await 來指定暫停點。 await 運算符通知編譯器異步方法:在等待的異步過程完成后才能繼續通過該點。 同時,控制返回至異步方法的調用方。
  2. 異步方法在 await 表達式執行時暫停並不構成方法退出,只會導致 finally 代碼塊不運行。
    標記的異步方法本身可以通過調用它的方法等待。

如果異步方法未使用 await 運算符標記暫停點,則該方法會作為同步方法執行,即使有 async 修飾符,也不例外。

I/O 綁定和CPU 綁定的不同編程方式:

  1. 如果工作為 I/O 綁定,使用 async 和 await(而不使用 Task.Run)。 不應使用任務並行庫。
  2. 如果工作屬於 CPU 綁定,並且重視響應能力,使用 async 和 await,但在另一個線程上使用 Task.Run 生成工作。 如果同時適用於並發和並行,應考慮使用任務並行庫。

類似於線程池工作項對異步操作的封裝,任務是對異步操作的另一種形式的封裝

任務啟動后,通過任務調度器TaskScheduler來調度。.NET中提供兩種任務調度器,一種是線程池任務調度器,也是默認調度器,它會將任務派發給線程池工作者線程;另一種是上下文同步任務調度器,它會將任務派發給當前上下文線程

async 方法被編譯成一個狀態機,結合task調度系統,實現語言運行時的協程

csharp語言內部實現了task的調度器,通過線程池來執行task,當一個task wait的時候,就 讓出線程,調度別的task在 線程上執行

await/async和線程沒有具體的關系,只是編譯器的語法糖,用於在編譯時是否轉換為狀態機,成為協程(協程也叫纖程),將await變成一個stackless協程由狀態機實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM