Async和Await 異步方法
Async和Await關鍵字是C#異步編程的核心。通過使用這兩個關鍵字,你可以使用.NET Framework或Windows Runtime的資源創建一個異步方法如同你創建一個同步的方法一樣容易。通過使用async和await定義的異步方法,這裏被稱為異步方法。
異步方法的特點:
方法中包含了 async 修飾符。
一個async方法按照慣例以“Async”結尾。
返回類型是如下類型之一:
Task<TResult> 當你的方法有返回值時,TResult即返回值的類型
Task 當你的方法沒有return語句,或者返回值並不參與任何形式的運算(包括賦值操作)。
Void 當你編寫一個異步事件處理時會用到。
方法通常包括至少一個await的表達式,這意味著該方法在遇到await時不能繼續執行,直到等待異步操作完成。在此期間,該方法將被暫停,並且控制權返回到該方法的調用者。
線程
異步方法的目的是不阻塞操作。在async方法中, await任務在執行的過程中,並不會阻塞當前的線程,其余的方法可以繼續執行,控制權將會移交到async方法的調用者。
async和await關鍵字並不會創建額外的線程,async方法不會去請求多線程操作。真正創建線程的操作是由Task.Run()實現的,一個async方法並不是在他自己的線程上執行的,只有當方法被激活時,才會使用當前線程的上下文和處理時間。
async方法要比BackgroundWorker更實用,而且使用起來更簡單而且不用去過多的考慮競態沖突神馬的。async方法會將運行中的代碼依據某些算法進行合理的拆分,並傳遞給線程池,這也是BackgroundWorker不能比的。
Async和Await
如果需要使用async或者await指定一個異步方法,我們需要註意一下兩點:
用async標記的異步方應該使用await關鍵子來制定掛起點。await操作符會告訴編譯器,這個async方放在完成之前,後面的代碼無法繼續執行,同時,控制權轉移到async方法的調用者。
標記為async的方法,調用時應使用await。
一個async方法裏通常包含一個或多個的對應的await操作符,但如果沒有await表達式也不會導致編譯錯誤。但如果調用一個async方 法,卻不使用await關鍵字來標記一個掛起點的話,程序將會忽略async關鍵字並以同步的方式執行。編譯器會對類似的問題發出警告。
返回類型和參數
在.NET Framework編程中,一個async方法通常返回的類型是Task或者Task<TResult>。在異步方法中,await操作符作用於從另外一個異步方法返回的Task。
如果指定Task<TResult>為返回結果,那麽這個方法必須包含return指定的TResult結果的語句。
如果使用Task作為返回值,那麽這個方法應該不存在使用return語句返回結果的代碼,或者返回的結果不參與任何運算(包括賦值操作)。
每一個返回的task都代表一個正在執行的工作,task包裝的信息中包含了這個異步方法的執行時的狀態,最終的結果,或者處理過程中拋出的異常。
如果返回值為void,這種類型主要使用於定義事件處理。異步事件通常被認為是一系列異步操作的開始。使用void返回類型不需要await,而且調用void異步方法的函數不會捕獲方法拋出的異常。
另外,async方法不能使用ref或者out參數,但是可以調用含有這些參數的方法。
命名約定
按照約定,你應該在異步方法的名稱後面追加“Async”用以標記此方法。但是在event,基類和接口中不需要遵守約定,就像本文例子中event處理函數Button1_Click一樣。
例子:
1 using System; 2 using System.Threading.Tasks; 3 4 namespace AsyncAndAwait { 5 class Program { 6 static void Main(string[] args) { 7 DisplayValue(); 8 Console.Write("Myclass End"); 9 Console.Read(); 10 } 11 12 13 public static Task<double> GetvalueAsync(double num1, double num2) { 14 return Task.Run(() => { 15 for(int i = 0; i < 10000; i++) { 16 num1 = num1 / num2; 17 18 } 19 return num1; 20 21 22 }); 23 } 24 public static async void DisplayValue() { 25 double result = await GetvalueAsync(1234.5, 1.01); 26 27 Console.Write("Value is:" + result); 28 29 } 30 } 31 }
Async和Await 異步方法