初步学习async/await,Task.GetAwaiter,Task.Result

初步学习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时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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 on 2024-09-25 12:46  漫思  阅读(8)  评论(0编辑  收藏  举报

导航