在for循環中使用await


在循環中調用多個函數,都使用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"));
        }
    }
}

 

結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM