新项目组用到Async & Await, 关于Await会不会新开不开线程,遇到什么情况会新开线程的问题网上查了很多资料都没看到直观的解释。现简单总结一下。
直接上代码:
class="brush:csharp;gutter:true;">namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Test(); Console.WriteLine("Current Thread Id1 :{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadKey(); } static async Task Test() { await Task.Run(new Action(GetName)); //Await 在这里必须搭配Task的新开线程方法使用,并且表示从这一行开始的剩余code在新线程中执行,并告诉Main线程继续往下执行。 Console.WriteLine("Current Thread Id2 :{0}", Thread.CurrentThread.ManagedThreadId); } public static void GetName() { for(int i=0; i<1000000000;i++) { int a = 15*15*15*15*15*15; } Console.WriteLine("Current Thread Id3 :{0}", Thread.CurrentThread.ManagedThreadId); } } }
结果如下
Current Thread Id1 :9
Current Thread Id3 :10
Current Thread Id2 :10
为了验证await是不是遇到新开启线程的方法才会触发他的作用,做如下更改。
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Test(); Console.WriteLine("Current Thread Id1 :{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadKey(); } static async Task Test() { await GetName(); Console.WriteLine("Current Thread Id2 :{0}", Thread.CurrentThread.ManagedThreadId); } public static async Task GetName() { for(int i=0; i<1000000000;i++) { int a = 15*15*15*15*15*15; } await Task.Delay(10000); Console.WriteLine("Current Thread Id3 :{0}", Thread.CurrentThread.ManagedThreadId); } } }
发现Main线程会等待GetName里的复杂运算结束后,知道Task.Delay才会继续执行Main线程,猜测正确。
补充一句,在第一段code中,如果在Test方法中的 await Task.Run(new Action(GetName)); 没有await, 代码跑到这里开启线程的同时Main线程会继续往下之前,因此await是包含了本行及以下的所有代码在新线程中执行,但仅限本方法及本方法调用的方法,不会进入上级方法。