15
11/2015
深入理解async和await(一)
C#中的await和async,一直都不是非常明白,其里头的具体机制如何?让我们先看一下下面的程序。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using System.Net; using System.Threading; using System.Threading.Tasks; namespace MyTest { class Program { static void Main(string[] args) { Console.WriteLine("Main before:" + Thread.CurrentThread.ManagedThreadId); Test(); Console.WriteLine("Main end:" + Thread.CurrentThread.ManagedThreadId); Console.ReadKey(); } static async Task Test() { Console.WriteLine("test before:" + Thread.CurrentThread.ManagedThreadId); await getName(); Console.WriteLine("test end:" + Thread.CurrentThread.ManagedThreadId); } static async Task<string> getName() { Console.WriteLine("name before:" + Thread.CurrentThread.ManagedThreadId); await Task.Delay(1000); Console.WriteLine("name end:" + Thread.CurrentThread.ManagedThreadId); return await Task<string>.Run(() => { Console.WriteLine("task before:" + Thread.CurrentThread.ManagedThreadId); return "irisloveleo"; }); } } }
上面的程序输入什么呢?想想,然后看下面的答案。
为什么会这样呢?让我们顺着这个答案反推出程序的执行过程。
1、开始进入main程序,当前的线程id为9
2、进入test函数,输出test before的线程id为9,表明此刻还没有产生新的线程,仍然顺序执行。
3、进入getName函数,输出name before的线程id为9,一直到此,都没有产生新的线程
4、下一步输出为Main end: 9,表明9线程(主线程)已经从getName函数退回到Test函数,但是Test函数在等待getName函数执行完毕,因此主线程继续退回到Main函数执行。
5、一秒之后,输出name end的线程为11,表明,从await Task.delay开始,新产生了一个线程
6、输出task before的线程id为12,表明此时有产生了一个新的线程
7、输出test end的线程id为12,表明利用的是getName中最后产生的那个线程,而本身不产生线程。
综上,可得出几个结论:
1、await并不产生新的线程,只有遇到真正的async方法,这个方法的内部会用Task.Run或者Task.Factory.StartNew 去开启线程
2、执行await后面语句的线程是async方法内产生的线程
3、Delay内部会产生一个新的线程用来控制延时,因此不会阻塞当前线程
转载请注明:康瑞部落 » 深入理解async和await(一)
0 条评论