async/await执行顺序

  测试后的理解,碰见Task.Run开始执行子线程,如果Task.Run存在await关键字(如果是Task方法函数,有无await主线程都会执行里面的,直到执行到Task.Run为止),

则主程序执行至这个Task.Run的await后会跳出去执行主线程原有的内容,await后面的内容会在子线程表结束后继续后面主线程未执行完的内容。

  如果加了async但是没有用到await,但是又用到了Task的返回值,如Task.Result,则主线程会等待子线程完成后才继续执行。

  await相当于线程跳出的点,在没碰到Task.Run(开启线程)并且await之前会继续执行,但是碰到后,会逐个根据Task跳出。

  如:

static void Main(string[] args)
        {

            //task->async异步方法和await,主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑
            Console.WriteLine("---------------------------------");
            Console.WriteLine("①1我是主线程,线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            var testResult = TestAsync();
            Console.WriteLine("2我是主线程,线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadKey();
        }

 

 static async Task TestAsync()
        {
            Console.WriteLine("②调用GetReturnResult()之前,线程ID:{0}。当前时间:{1}", Thread.CurrentThread.ManagedThreadId,
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
            var name =  InTask();//1主线程进入方法。3主线程跳出InTask()后继续执行。(假如下面6的await在这里,那么4也是又1.1完成)
            // name;
            Console.WriteLine("④调用GetReturnResult()之后,线程ID:{0}。当前时间:{1}", Thread.CurrentThread.ManagedThreadId,
                DateTime.Now.ToString("yyyy-MM-dd hh:MM:ss"));
            Console.WriteLine("⑥得到GetReturnResult()方法的结果一:{0}。当前时间:{1}", await name,//4碰到await主线程跳出此方法,执行TestAsync()外的逻辑
                Thread.CurrentThread.ManagedThreadId);//这里由1.1来完成
            Console.WriteLine("⑥得到GetReturnResult()方法的结果二:{0}。当前时间:{1}", name, //这里也是由1.1来完成
                Thread.CurrentThread.ManagedThreadId);
        }



        static async Task<string> InTask()
        {
            Console.WriteLine("InTask执行Task.Run之前, 线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            var w = await Task.Run(GetReturnResult3);//2.主线程碰到开启子线程方法,并且有await,跳出方法,执行方法外部逻辑。
            Console.WriteLine("InTask执行Task.Run后, 线程ID:{0}", Thread.CurrentThread.ManagedThreadId);//这里由1.1开始继续完成
            return w;
        }


        static async Task<string> GetReturnResult3()
        {
            Thread.Sleep(20);//子线程1开始
            Console.WriteLine("③执行Task.Run之前, 线程ID:{0}", Thread.CurrentThread.ManagedThreadId);
            var a = Task.Run(() => //子线程的子线程,叫1.1。开始
            {
                Thread.Sleep(2000);
                Console.WriteLine("⑤GetReturnResult()方法里面线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
                return "我是返回值";//1.1 因为他是嵌套的最后一层,所以它并没有结束,而是跳出去,执行主线程没有完成的部分。
            });
            Thread.Sleep(20);
            Console.WriteLine("③.1执行Task.Run后, 线程ID:22{0}", Thread.CurrentThread.ManagedThreadId);//理论这里应该是子线程1完成,因为程序在这里执行完后才开始等待2秒的,
//
那么应该是由子线程1完成的才对,但是线程ID和子线程ID完全不一样。也不是1.1线程。不知道为什么
return await a;//子线程1跳出。这里子线程已经结束了
        }

所有主线程跳出的方法后面的内容都由子线程完成,套了多个Task.Run的情况下,只完成当前线程内的,由套在里面的子线程完成主线程剩下的部分。

 

posted @ 2020-11-04 14:46  mimo0  阅读(1141)  评论(0)    收藏  举报