在.NET Framework4.5框架、C#5.0語法中,經過async和await兩個關鍵字,引入了一種新的基於任務的異步編程模型(TAP)。在這種方式下,能夠經過相似同步方式編寫異步代碼,極大簡化了異步編程模型。html
用法:web
public async Task<int> GetDotNetCountAsync()
{
// Suspends GetDotNetCount() to allow the caller (the web server)
// to accept another request, rather than blocking on this one.
var html = await _httpClient.GetStringAsync("https://dotnetfoundation.org");
return Regex.Matches(html, @"\.NET").Count;
}
要點!!!編程
1.「async」用來標記一個方法爲異步方法,異步方法體內需結合「await」關鍵字使用,若是沒有await,則該方法等同於一個普通方法。異步方法命名規則一般以Async結尾。框架
2.「await」關鍵字只能在異步方法中使用。異步
3.當在async異步方法中遇到await操做時,await會阻塞該異步方法不繼續往下執行,並將該異步方掛起,將控制權轉到該異步方法的調用者手中。async
4.異步方法的調用者得到控制權以後:異步編程
1)若是調用者須要使用異步方法的返回結果,則繼續等待異步方法執行完畢,再繼續往下執行。函數
2)若是調用者不關心異步方法的返回結果,則繼續往下執行。this
場景一:async方法中未使用awaitspa
static void Main(string[] args) { Console.WriteLine("執行前Main.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟① GetResultAsync(); Console.WriteLine("執行結束Main....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟② Console.ReadKey(); } async static Task<int> GetResultAsync() { Console.WriteLine("執行前GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟③
Task.Delay(3000).Wait(); Console.WriteLine("執行結束GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟④ return 10; }
執行結果:步驟① ——>步驟③——>步驟④——> 步驟②
結果分析:
咱們會發現,主函數Main調用異步方法GetResultAsync時,因爲異步方法缺乏「await」關鍵字,主函數需等異步方法步驟3,4所有執行結束後再繼續執行步驟2,執行順序徹底和同步方法執行順序一致;
而且異步方法會給出語法提示:缺乏「await」關鍵字
場景2:異步方法體內遇到await以後,當即將控制權轉到調用者手中
static void Main(string[] args) { Console.WriteLine("執行前Main.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟①
GetResultAsync(); Console.WriteLine("執行結束Main....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟② Console.ReadKey(); } async static Task<int> GetResultAsync() { Console.WriteLine("執行前GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟③ await Task.Delay(3000); Console.WriteLine("執行結束GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟④ return 10; }
執行結果:步驟① ——>步驟③——>步驟②——> 步驟④
結果分析:
咱們會發現,主函數Main調用異步方法GetResultAsync,在遇到異步方法中「await」關鍵字時
1)阻塞了當前異步方法並當即將控制權轉交給調用者主函數Main
2)主函數得到控制權後繼續執行方法體內步驟2,GetResultAsync方法則異步執行(等待異步操做結束以後執行步驟4)。
場景3:異步方法體內遇到await以後,當即將控制權轉到調用者手中,調用者需等待異步方法返回結果
static void Main(string[] args) { Console.WriteLine("執行前Main.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟① Task<int> res = GetResultAsync(); Console.WriteLine("執行結束Main....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟② Console.WriteLine("執行結果:" + res.Result + "....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟③ Console.ReadKey(); } async static Task<int> GetResultAsync() { Console.WriteLine("執行前GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟④ await Task.Delay(3000); Console.WriteLine("執行結束GetResult.....線程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());//步驟⑤ return 10; }
執行結果:步驟① ——>步驟④——>步驟②——> 步驟⑤——> 步驟③
結果分析:
咱們會發現,主函數Main調用異步方法GetResultAsync,在遇到異步方法中「await」關鍵字時
1)阻塞了當前異步方法並當即將控制權轉交給調用者主函數Main
2)主函數得到控制權後繼續執行方法體內步驟2和步驟3,GetResultAsync方法則異步執行。
3)當主函數執行步驟3時,因爲步驟3須要打印異步方法的返回結果,故須要等待異步方法結束才能繼續。因此需先執行步驟5,而後再繼續執行步驟3。
最後,異步編程的時候咱們一般會結合Task來使用,感興趣的同窗能夠了解一下。厚積薄發!!!