1. 程式人生 > >async & await的學習筆記

async & await的學習筆記

非同步程式設計筆記:

場景:在一個Fun中獲取使用者的ID,姓名,金額.其中.使用者的金額是另一個介面返回的..

同步程式設計步驟

Fun()

{

  1. 獲取使用者ID,姓名         =====>假設耗時3秒

  2.呼叫介面獲取使用者金額     ======>假設耗時4秒

  3.組裝資料,返回結果      ======>假設耗時0.1秒

}

 

此時該Fun()的執行時間是>=7.1秒.

非同步程式設計步驟

Fun2()

{

  1.獲取使用者ID,姓名          =====>假設耗時3秒

  1-1:同時開啟新執行緒獲取使用者金額  =====>假設耗時4秒

  2.當1-1返回資料後,組裝資料,返回結果.   ===> 在執行Fun2()的第4~5秒時就開始執行了. ,假設耗時0.1秒

}

Fun2()的執行時間是>=4.1秒, 

 

上面是使用場景以及不同策略給出的理論資料..下面看程式碼:

 

namespace AsyncLearn
{
    class Program
    {
        static void Main(string[] args)
        {
            List<A> list = new List<A>();
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Console.WriteLine("async get money");//非同步執行緒獲取金額
            var blistFun = GetMoney(); Console.WriteLine("process mainThread");//主執行緒邏輯設定主資料 for (int i = 0; i < 10; i++) { Thread.Sleep(200); list.Add(new A { id = i + 1, name = "mainThread" + i }); } Console.WriteLine("start set money !!!");//重點看這句列印的先後順序 blistFun.Result.ForEach((b) => { var item = list.FirstOrDefault(s => s.id == b.id); if (item != null) { item.money = b.money;Console.WriteLine($"set {item.name}"); } }); sw.Stop(); Console.WriteLine("stop set money"); Console.WriteLine("Finished " + sw.Elapsed.TotalSeconds); Console.ReadKey(); } static async Task<List<B>> GetMoney() { Console.WriteLine("start process money"); List<B> blist = new List<B>(); await Task.Run(() => { for (int i = 1; i < 15; i += 2) { Thread.Sleep(100);//修改此處時間,觀察帶"!!!"的訊息 blist.Add(new B { id = i, money = i * 3 }); } }); Console.WriteLine("stop process money !!!");//重點看這句列印的先後順序 return blist; } } public class A { public int id { get; set; } public string name { get; set; } public int money { get; set; } } public class B { public int id { get; set; } public int money { get; set; } } }

 

當GetMoney介面處理速度較快時, Thread.Sleep(100);

 

在合併資料之前就已經完成了..

當我們把GetMoney 介面處理時間加長:Thread.Sleep(800);

 

此時,帶"!!!"的列印位置發生變更了..

 

現在,我們來驗證下5.64秒的程式碼變更成單執行緒執行..

 1 namespace AsyncLearn
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6  { 7 List<A> list = new List<A>(); 8 Stopwatch sw = new Stopwatch(); 9  sw.Start(); 10 Console.WriteLine("async get money");//非同步執行緒獲取金額 11 var blistFun =GetMoney().Result; 12 Console.WriteLine("process mainThread");//主執行緒邏輯設定主資料 13 for (int i = 0; i < 10; i++) 14  { 15 Thread.Sleep(200); 16 list.Add(new A 17  { 18 id = i + 1, 19 name = "mainThread" + i 20  }); 21  } 22 Console.WriteLine("start set money !!!");//重點看這句列印的先後順序 23 blistFun.ForEach((b) => { 24 var item = list.FirstOrDefault(s => s.id == b.id); 25 if (item != null) { item.money = b.money;Console.WriteLine($"set {item.name}"); } 26  }); 27  sw.Stop(); 28 Console.WriteLine("stop set money"); 29 30 Console.WriteLine("Finished " + sw.Elapsed.TotalSeconds); 31  Console.ReadKey(); 32  } 33 34 static async Task<List<B>> GetMoney() 35  { 36 Console.WriteLine("start process money"); 37 List<B> blist = new List<B>(); 38 await Task.Run(() => 39  { 40 for (int i = 1; i < 15; i += 2) 41  { 42 Thread.Sleep(800);//修改此處時間,觀察帶"!!!"的訊息 43 blist.Add(new B 44  { 45 id = i, 46 money = i * 3 47  }); 48  } 49  }); 50 Console.WriteLine("stop process money !!!");//重點看這句列印的先後順序 51 return blist; 52  } 53  } 54 public class A 55  { 56 public int id { get; set; } 57 public string name { get; set; } 58 59 public int money { get; set; } 60  } 61 62 public class B 63  { 64 public int id { get; set; } 65 public int money { get; set; } 66  } 67 }

主要變化了第11行和第23行.

執行結果為:

 

關於非同步程式設計的簡單用法就先寫到這..後期有比較好的場景,和其他用法,再來寫點~  歡迎點評~