async & await的學習筆記
阿新 • • 發佈:2018-11-20
非同步程式設計筆記:
場景:在一個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行.
執行結果為:
關於非同步程式設計的簡單用法就先寫到這..後期有比較好的場景,和其他用法,再來寫點~ 歡迎點評~