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);
结果如下:
从上面可以看出,运行Task.Run时会开启一个新线程。这里使用了2个Task.Run,一个带await,另一个不带,结果两个都开启了一个新的线程。
为啥这样的结果,因为async/await本质上是.NET的语法,从某种意义上跟普通方法一样,不占用线程,所以这里跟主线程一样;如果出现多个async/await的时候,.NET编译器在后台会对方法执行异步处理。那么在Task.Run在普通方法里当然会新增加一个线程了,async/await方法其实就是个普通方法。
结语
该问题主要考察对async/await的理解,以及对Task.Run的熟悉程度。本文用案例讲述了问题的结果,答案仅供参考。同时欢迎留言,并提出您的宝贵见解!