初步學習async/await,Task.GetAwaiter,Task.Result


   網上關於async/await的知識有很多,看了很多但不如自己實踐一遍來得快,所以這里記錄下我的理解和大家學習下。

   首先以最簡單的同步方法來開始如下

 private static   void Test()
        {

            Console.WriteLine(2);
            GetV();
            Console.WriteLine(6);
        }
        private static  void GetV()
        {
            Console.WriteLine(3);
           Console.WriteLine(4);
            Console.WriteLine(5);
        }

        static void Main(string[] args)
        {

            Console.WriteLine(1);
           Test();
            Console.WriteLine(7);
       } 

輸出如下

 

 

 當時當我們簡單的使用Task.Run時

  private static   void Test()
        {

            Console.WriteLine(2);
            GetV();
            Console.WriteLine(6);
        }
        private static  void GetV()
        {
            Console.WriteLine(3);
            Task.Run(() =>
            {
                Thread.Sleep(10000);
                Console.WriteLine(4);
            });
            Console.WriteLine(5);
        }

        static void Main(string[] args)
        {

            Console.WriteLine(1);
           Test();
            Console.WriteLine(7);
         }

  

,因為分配了新的線程,所以4會最晚打印出來。

 

 這時候我們使用async/await呢?

 private static async Task Test()
        {

            Console.WriteLine(2);
            await  GetV();
            Console.WriteLine(6);
        }
        private static async Task GetV()
        {
            Console.WriteLine(3);
            await Task.Run(() =>
            {
                Thread.Sleep(10000);
                Console.WriteLine(4);
            });
            Console.WriteLine(5);
            
        }

        static void Main(string[] args)
        {

            Console.WriteLine(1);
            var v= Test();
            Console.WriteLine(7);
       }

 

因為await會時被修飾的代碼處於等待狀態,就相當於阻塞那段代碼,Test方法里面執行到await時就會等待Getv的方法的執行,就會阻塞Test方法,但是不會阻塞Main方法,可以理解為await將阻塞的控制權交給了Test方法。所以這個時候打印結果為

 

 但是當我們把Test的await去掉了,這時候Test方法就沒有了阻塞的權限,而是去尋找下一個await來轉移控制權,如下

   private static void Test()
        {

            Console.Out.WriteLine(2);
            GetV();
            Console.Out.WriteLine(6);
        }
        private static async Task GetV()
        {
            Console.Out.WriteLine(3);
            await Task.Run(() =>
            {
                Thread.Sleep(10000);
                Console.WriteLine(4);
            });
            Console.Out.WriteLine(5);
            
        }

        static void Main(string[] args)
        {

            Console.Out.WriteLine(1);
            Test();
            Console.Out.WriteLine(7);
            string str = Console.ReadLine();
       }

這個時候就不會阻塞Test方法,結果如下

 

如果在main方法里面使用Task.GetAwaiter或者Task.Result呢,這兩個東西我的理解就是阻塞線程,等待異步返回結果,但是它阻塞的是當前的方法,如下代碼

        private static async Task Test()
        {

            Console.Out.WriteLine(2);
            GetV();
            Console.Out.WriteLine(6);
        }
        private static async Task GetV()
        {
            Console.Out.WriteLine(3);
            await Task.Run(() =>
            {
                Thread.Sleep(10000);
                Console.WriteLine(4);
            });
            Console.Out.WriteLine(5);
            
        }

        static void Main(string[] args)
        {

            Console.Out.WriteLine(1);
            Test().GetAwaiter().GetResult() ;
            Console.Out.WriteLine(7);
            string str = Console.ReadLine();
         }

它只會阻塞main方法的,但是對於Test方法它是無法阻塞的,Test方法仍然會異步執行,4,5仍然以異步的方法打印出來,所以打印結果如下

 

 Task.Result也是如此,只會阻塞當前的方法,我覺得和await相似,只給了當前使用Task.GetAwaiter或者Task.Result的方法阻塞全,沒有權利阻塞別的方法。

 

 

 

 

 

 

打個廣告:游戲也能賺錢?如果你熱愛游戲,並且想通過游戲贏得零花錢,5173是個不錯的選擇  

 


免責聲明!

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



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