第十节:利用async和await简化异步编程模式的几种写法
一. async和await簡介
PS:簡介
1. async和await這兩個關鍵字是為了簡化異步編程模型而誕生的,使的異步編程更簡潔,它本身并不創(chuàng)建新線程,但在該方法內部開啟多線程,則另算。
2.?這兩個關鍵字適用于處理一些文件IO操作。
3.?好處:代碼簡介,把異步的代碼寫成了同步的形式,提高了開發(fā)效率。
壞處:如果使用同步思維去理解,容易出問題,返回值對不上。
?
二. 幾種用法
情況1:當只有async,沒有await時,方法會有個警告,和普通的多線程方法沒有什么區(qū)別,不存在線程等待的問題。
代碼實踐:
?
1 private static async void Test1()2 {3 //主線程執(zhí)行4 Console.WriteLine("主線程{0}開始:", Thread.CurrentThread.ManagedThreadId);5 //啟動新線程完成任務6 Task task = Task.Run(() =>7 {8 Console.WriteLine("子線程{0}開始:", Thread.CurrentThread.ManagedThreadId);9 Thread.Sleep(3000); 10 Console.WriteLine("子線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 11 }); 12 //主線程執(zhí)行 13 Console.WriteLine("主線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 14 }?
代碼結果:
情況2:不推薦void返回值,使用Task來代替Task和Task<T>能夠使用await, Task.WhenAny, Task.WhenAll等方式組合使用,async Void 不行。
代碼實踐:
?
1 /// <summary>2 /// 不推薦void返回值,使用Task來代替3 /// Task和Task<T>能夠使用await, Task.WhenAny, Task.WhenAll等方式組合使用。async Void 不行4 /// </summary>5 private static async void Test2()6 {7 //主線程執(zhí)行8 Console.WriteLine("主線程{0}開始:", Thread.CurrentThread.ManagedThreadId);9 //啟動新線程完成任務 10 Task task = Task.Run(() => 11 { 12 Console.WriteLine("子線程{0}開始:", Thread.CurrentThread.ManagedThreadId); 13 Thread.Sleep(3000); 14 Console.WriteLine("子線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 15 }); 16 await task; //等待子線程執(zhí)行完畢,方可執(zhí)行后面的語句 17 Console.WriteLine("主線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 18 }?
代碼結果:
?
情況3:async Task == async void。 區(qū)別:Task和Task<T>能夠使用await, Task.WhenAny, Task.WhenAll等方式組合使用,async Void 不行。
代碼實踐:
?
1 /// <summary>2 /// 無返回值 async Task == async void3 /// Task和Task<T>能夠使用await, Task.WhenAny, Task.WhenAll等方式組合使用,async Void 不行4 /// </summary>5 private static async Task Test3()6 {7 //主線程執(zhí)行8 Console.WriteLine("主線程{0}開始:", Thread.CurrentThread.ManagedThreadId);9 //啟動新線程完成任務 10 Task task = Task.Run(() => 11 { 12 Console.WriteLine("子線程{0}開始:", Thread.CurrentThread.ManagedThreadId); 13 Thread.Sleep(3000); 14 Console.WriteLine("子線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 15 }); 16 await task; //等待子線程執(zhí)行完畢,方可執(zhí)行后面的語句 17 Console.WriteLine("主線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 18 }?
代碼結果:
?
情況4和情況5:說明要使用子線程中的變量,一定要等子線程執(zhí)行結束后再使用。
代碼實踐:
?
1 /// <summary>
2 /// 帶返回值的Task,要使用返回值,一定要等子線程計算完畢才行
3 /// </summary>
4 /// <returns></returns>
5 private static async Task<long> Test4()
6 {
7 //主線程執(zhí)行
8 Console.WriteLine("主線程{0}開始:", Thread.CurrentThread.ManagedThreadId);
9 long result = 0;
10 //啟動新線程完成任務
11 Task task = Task.Run(() =>
12 {
13 for (long i = 0; i < 100; i++)
14 {
15 result += i;
16 }
17 });
18 await task; //等待子線程執(zhí)行完畢,方可執(zhí)行后面的語句
19 Console.WriteLine("主線程{0}結束:", Thread.CurrentThread.ManagedThreadId);
20 Console.WriteLine("result:{0}", result);
21 return result;
22 }
?
?
1 /// <summary>2 /// 帶返回值的Task,要使用返回值,一定要等子線程計算完畢才行3 /// 與情況四形成對比,沒有等待,最終結果不準確4 /// </summary>5 /// <returns></returns>6 private static Task<long> Test5()7 {8 //主線程執(zhí)行9 Console.WriteLine("主線程{0}開始:", Thread.CurrentThread.ManagedThreadId); 10 long result = 0; 11 //啟動新線程完成任務 12 TaskFactory taskFactory = new TaskFactory(); 13 Task<long> task = taskFactory.StartNew<long>(() => 14 { 15 for (long i = 0; i < 100; i++) 16 { 17 result += i; 18 } 19 return 1; 20 }); 21 Console.WriteLine("主線程{0}結束:", Thread.CurrentThread.ManagedThreadId); 22 Console.WriteLine("result:{0}", result); 23 return task; 24 }?
代碼結果:
? 以上兩種情況,第一種情況含有線程等待的結果為4950,第二個情況么有線程等待,結果不準確(即共享變量競用問題)。
總結
以上是生活随笔為你收集整理的第十节:利用async和await简化异步编程模式的几种写法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 印度再遭打击,GDP增速被下调至-3.4
- 下一篇: 软件测试计划时要记住什么