一、涉及內容
async & await是C# 5.0引入的,控制臺輸出所使用的$符號(拼接字串)是C# 6.0引入的,其功能類似于string.Format()方法,
二、多執行緒、異步、同步之間的聯系與區別
廚房案例:
比如說你要炒5道菜ABCDE,但是只有兩個爐子可以用,即同時只能炒兩道菜,在這里,爐子就是執行緒,
假如兩個爐子分別同時炒A和B,那剩下的CDE只能等A或B炒完了才能開始,這個等待的程序就是同步,我們稱之為阻塞,即這個時候你只能炒A和B這兩道菜,
假如你還有一臺咖啡機,在你炒A和B的時候順手把咖啡豆和水放到咖啡機里打開開關,然后你就不用管它了,此時,就是新開了一個執行緒去煮咖啡,而煮咖啡
是由咖啡機自動完成的并不影響繼續炒菜,所以煮咖啡這個執行緒是異步的,我們稱之為非阻塞,
當咖啡機叮的一聲通知你咖啡已經煮好了,你要去把咖啡拿出來加點糖或奶什么的,這個拿咖啡的動作我們稱之為回呼,這個是咖啡機執行緒完成之后通知你要去
做的動作,
簡單來說:
會占用你的時間讓你無法去做其它事情的任務叫做同步任務(炒菜要專注否則會糊鍋),
那些不需要占用你的時間的任務叫做異步任務(咖啡機自己會把咖啡煮好,不需要你一直看著它),
下面代碼演示不使用異步的情況:
class Program { //創建計時器 private static readonly Stopwatch stopwatch = new Stopwatch(); static void Main(string[] args) { #region async & await入門一之不使用異步 //啟動計時器 stopwatch.Start(); //URL地址 const string url1 = "http://www.cnblogs.com/"; const string url2 = "http://www.cnblogs.com/atomy/"; //異步下載某網站內容,并統計字符的個數, var result1 = CountCharacters("url1", url1); var result2 = CountCharacters("url2", url2); //主要是通過拼接字串達到耗時操作 for (var i = 0; i < 3; i++) { ExtraOperation(i + 1); } //控制臺輸出 Console.WriteLine($"{url1} 的字符個數:{result1}"); Console.WriteLine($"{url2} 的字符個數:{result2}"); Console.WriteLine($"總耗時{stopwatch.ElapsedMilliseconds}ms,"); Console.Read(); #endregion } /// <summary> /// 統計字符個數 /// </summary> /// <param name="id"></param> /// <param name="address"></param> /// <returns></returns> private static int CountCharacters(string name, string address) { var wc = new WebClient(); Console.WriteLine($"{name}開始呼叫,歷時{stopwatch.ElapsedMilliseconds}ms,執行緒id={Thread.CurrentThread.ManagedThreadId},"); var result = wc.DownloadString(address); Console.WriteLine($"{name}呼叫完成,歷時{stopwatch.ElapsedMilliseconds}ms,執行緒id={Thread.CurrentThread.ManagedThreadId},"); return result.Length; } /// <summary> /// 額外操作 /// </summary> /// <param name="id"></param> private static void ExtraOperation(int id) { //這里是通過拼接字串進行一些相對耗時的操作 var s = ""; for (var i = 0; i < 6000; i++) { s += i; } Console.WriteLine($"第{id}次ExtraOperation執行完成,歷時:{stopwatch.ElapsedMilliseconds}ms,"); } }View Code
運行結果如下:

下面代碼演示使用異步的情況:
class Program { //創建計時器 private static readonly Stopwatch stopwatch = new Stopwatch(); static void Main(string[] args) { #region async & await入門一之使用異步 //啟動計時器 stopwatch.Start(); //URL地址 const string url1 = "http://www.cnblogs.com/"; const string url2 = "http://www.cnblogs.com/atomy/"; //異步下載某網站內容,并統計字符的個數, Task<int> t1 = CountCharactersAsync("url1", url1); Task<int> t2 = CountCharactersAsync("url2", url2); //主要是通過拼接字串達到耗時操作 for (var i = 0; i < 3; i++) { ExtraOperation(i + 1); } //控制臺輸出 Console.WriteLine($"{url1} 的字符個數:{t1.Result}"); Console.WriteLine($"{url2} 的字符個數:{t2.Result}"); Console.WriteLine($"總耗時{stopwatch.ElapsedMilliseconds}ms,"); Console.Read(); #endregion } /// <summary> /// 統計字符個數 /// </summary> /// <param name="id"></param> /// <param name="address"></param> /// <returns></returns> private static async Task<int> CountCharactersAsync(string name, string address) { var wc = new WebClient(); Console.WriteLine($"{name}開始呼叫,歷時{stopwatch.ElapsedMilliseconds}ms,執行緒id={Thread.CurrentThread.ManagedThreadId},"); var result =await wc.DownloadStringTaskAsync(address); Console.WriteLine($"{name}呼叫完成,歷時{stopwatch.ElapsedMilliseconds}ms,執行緒id={Thread.CurrentThread.ManagedThreadId},"); return result.Length; } /// <summary> /// 額外操作 /// </summary> /// <param name="id"></param> private static void ExtraOperation(int id) { //這里是通過拼接字串進行一些相對耗時的操作 var s = ""; for (var i = 0; i < 6000; i++) { s += i; } Console.WriteLine($"第{id}次ExtraOperation執行完成,歷時:{stopwatch.ElapsedMilliseconds}ms,"); } }View Code
運行結果如下:

三、async & await 結構
async & await結構可分成三部分:
1)呼叫方法:該方法呼叫異步方法,然后在異步方法執行其任務的時候繼續執行,
2)異步方法:該方法異步執行作業,然后立刻回傳到呼叫方法,
3)await運算式:用于異步方法內部,指出需要異步執行的任務,


四、異步方法
異步方法:在執行完成前立即回傳呼叫方法,在呼叫方法繼續執行的程序中完成任務,
語法分析:
1)關鍵字:方法頭回傳型別前使用async關鍵字,它是一個背景關系關鍵字, 2)要求:需有await運算式(可多個)方可進行異步操作,否則視為普通方法進行同步操作, 3)回傳型別:只能回傳3種型別(void、Task和Task<T>),Task和Task<T>標識回傳的物件會在將來完成作業,表示呼叫方法和異步方法可以繼續執行, 4)引數:數量不限,但不能使用out和ref關鍵字, 5)命名約定:方法后綴名應以Async結尾, 6)其它:匿名方法和 Lambda 運算式也可以作為異步物件,
參考自:
https://www.cnblogs.com/woxihuadabai/p/8042652.html
https://www.cnblogs.com/liqingwen/p/5831951.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/91562.html
標籤:C#
