初步学习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是个不错的选择  

 

posted @ 2019-11-13 16:07  灬丶  阅读(3456)  评论(4编辑  收藏  举报