在async/await中使用Task.Run异步会启动新线程吗?

async/await是常考的面试题,这不小白昨天又遇到一道题,面试官问到async/await是说“在async/await中使用Task.Run异步会启动新线程吗?”这个问题,当时小白回答是会开启新线程,答案是正确的吗?Task.Run是开启多线程的一种方式,而async/await是.NET异步的语法糖,通常async/await是走主线程而不会新开线程,它内部原理是状态机(这里就不多讲了)。针对本话题到底会不会启动新的线程,我们用实例说话。

实例

这里新建一个控制台程序,再建一个async/await方法和普通方法,然后在async/await的方法里新建一个Task.Run多线程。并且在每个方法中输出线程ID。.

//async await  async Task<string> Dosomething(){    var ThreadId= Thread.CurrentThread.ManagedThreadId.ToString();    Console.WriteLine("这是async线程:"+ThreadId);    await Task.Run(() => TaskFun());//异步调用     Task.Run(() =>    {        var ThreadId = Thread.CurrentThread.ManagedThreadId.ToString();        Console.WriteLine("这是Run2线程:" + ThreadId);        Console.WriteLine("Do Work2");    });//不使用异步调用    return "I am done";} void TaskFun(){    var ThreadId = Thread.CurrentThread.ManagedThreadId.ToString();    Console.WriteLine("这是Run线程:"+ ThreadId);    Console.WriteLine("Do Work");}//调用var rel= Dosomething().Result;Console.WriteLine(rel);var ThreadId = Thread.CurrentThread.ManagedThreadId.ToString();Console.WriteLine("这是主线程:" + ThreadId);

结果如下:

在async/await中使用Task.Run异步会启动新线程吗?

从上面可以看出,运行Task.Run时会开启一个新线程。这里使用了2个Task.Run,一个带await,另一个不带,结果两个都开启了一个新的线程。

为啥这样的结果,因为async/await本质上是.NET的语法,从某种意义上跟普通方法一样,不占用线程,所以这里跟主线程一样;如果出现多个async/await的时候,.NET编译器在后台会对方法执行异步处理。那么在Task.Run在普通方法里当然会新增加一个线程了,async/await方法其实就是个普通方法。

结语

该问题主要考察对async/await的理解,以及对Task.Run的熟悉程度。本文用案例讲述了问题的结果,答案仅供参考。同时欢迎留言,并提出您的宝贵见解!