在循環中調用多個函數,都使用await的話,和同步效果一樣。
public static async void fun1() { string str = ""; Console.WriteLine("同步開始"); for (int i = 0; i < 10; i++) { str+= await fun2(i)+"\n"; } Console.WriteLine("同步結束"); } public static async Task<int> fun2(int i) { await Task.Delay(1000); Console.WriteLine(i+"--fun2--"+DateTime.Now.ToString("HH:mm:ss.fff")); return Convert.ToInt32(DateTime.Now.ToString("fff")); }
結果如下:
不是用await關鍵字可以事先異步調用多個函數,但是並不清楚每個函數執行結果如何
public static async void fun1() { #region 循環內 調用函數 異步 Console.WriteLine("異步調用開始,不考慮函數執行結果"); for (int i = 0; i < 10; i++) { fun2(i);//異步方式,不接收返回值 } Console.WriteLine("異步調用結束,不考慮函數執行結果"); #endregion } public static async Task<int> fun2(int i) { await Task.Delay(1000); Console.WriteLine(i+"--fun2--"+DateTime.Now.ToString("HH:mm:ss.fff")); return Convert.ToInt32(DateTime.Now.ToString("fff")); }
結果如下:
當需要清楚每個函數執行結果時,需要使用到Tuple(元組)
public static async void fun1() { Console.WriteLine("異步調用開始,需要等待每個函數的結果"); var list = new List<Task<Tuple<int,bool>>>(); for (int i = 0; i < 10; i++) { list.Add(write(i)); } foreach (var item in await Task.WhenAll(list)) { Console.WriteLine(item.Item1+","+item.Item2); } Console.WriteLine("異步調用結束,需要等待每個函數的結果"); } public static async Task<Tuple<int,bool>> write(int i) { //Thread.Sleep(1000); await Task.Delay(1000); Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff")); return Tuple.Create(i,true); }
結果如下:
元組Tuple<>可定義多個類型的變量,用於接收返回值;以上代碼中定義了<int,bool>,使用int標識第幾個函數,bool標識執行狀態。
將for循環內的函數,添加到var list =new List<Task<Tuple<int,bool>>>()中。
使用await Task.WhenAll(list) 進行調用。返回內容包含 int 和bool 兩個值,使用Item1 和Item2 調用。
被調用的函數需要將返回類型改為 Task<Tupe<int,bool>>;執行完畢后,return Trple.Create(i,true);//這里按實際返回內容
整體是這個意思,我還沒弄懂原理;
完整代碼如下:
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace ConsoleApp2 { class Program { static void Main(string[] args) { fun1(); Console.WriteLine("主"+DateTime.Now.ToString("HH:mm:ss.fff")+"\n"); Console.ReadLine(); } public static async void fun1() { #region 循環內 調用函數 同步 string str = ""; Console.WriteLine("同步開始\n"); for (int i = 0; i < 10; i++) { str+= await fun2(i)+"\n"; } Console.WriteLine("同步結束\n"); #endregion 結束 #region 循環內 調用函數 異步 Console.WriteLine("異步調用開始,不考慮函數執行結果\n"); for (int i = 0; i < 10; i++) { fun2(i);//異步方式,不接收返回值 } Console.WriteLine("異步調用結束,不考慮函數執行結果\n"); Console.WriteLine("異步調用開始,需要等待每個函數的結果\n"); var list = new List<Task<Tuple<int,bool>>>(); for (int i = 0; i < 10; i++) { list.Add(write(i)); } foreach (var item in await Task.WhenAll(list)) { Console.WriteLine(item.Item1+","+item.Item2); } Console.WriteLine("異步調用結束,需要等待每個函數的結果\n"); #endregion } public static async Task<Tuple<int,bool>> write(int i) { //Thread.Sleep(1000); await Task.Delay(1000); Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff")); return Tuple.Create(i,true); } public static async Task<int> fun2(int i) { await Task.Delay(1000); Console.WriteLine(i+"--fun2--"+DateTime.Now.ToString("HH:mm:ss.fff")); return Convert.ToInt32(DateTime.Now.ToString("fff")); } } }
結果如下: