在"真正的异步"使用async-await的代码,仍然有一些"线程"那是等待的?

时间:2017-09-30 20:53:31

标签: c# .net multithreading asynchronous async-await

我们说我正确使用async - await,就像

一样
await client.GetStringAsync("http://stackoverflow.com");

我理解调用await的线程变为" free",也就是说,调用链上的某些东西不会执行某个等效的循环

bool done = false;
string html = null;
for(; !done; done = GetStringIfAvailable(ref html));

如果我调用GetStringAsync的同步版本(按惯例可能称为GetString),它将会做什么。

然而,在这里我感到困惑。即使调用线程或应用程序的可用线程池中的任何其他线程没有被这样的循环阻止,那么事情就是,因为据我所知,在低级别总是有轮询进行。因此,我不是简单地降低工作总量,而是简单地将工作推向某些事情。我的应用程序的线程......或类似的东西。

有人可以为我清楚吗?

2 个答案:

答案 0 :(得分:2)

没有

编译器会将使用async / await的方法转换为可以分解为多个步骤的状态机。一旦命中await,就会存储方法的状态并执行#34; offloaded"回到调用它的线程。如果任务正在等待磁盘IO这样的事情,操作系统内核将最终依赖物理CPU中断让内核知道何时发出应用程序信号以恢复处理。挂起挂起方法的状态,并在可用线程上排队(如果awaitConfigureAwait,则为true的同一线程;如果为false,则为任何空闲线程})(最后一部分并非完全正确,请参阅Scott Chamberlain的评论。)。可以把它想象成event,应用程序要求硬件“ping”#34;一旦工作完成,应用程序就会回到以前做的任何事情。

在等待它完成时阻塞。

重要的是要记住,使用Task.Run / ThreadPool的异步操作都是关于暂停,存储,检索和恢复该状态机。它并不真正关心async内发生的事情,那里发生的事情以及它是如何发生的,并不与await / Task直接相关。

我对async / await感到非常困惑,直到我真正理解该方法如何转换为状态机。编译器在exactly what your async methods get converted to上阅读可能有所帮助。

答案 1 :(得分:-2)

你把它推到了操作系统上 - 如果它可以而不是简单地等待,它将运行一些其他线程。当它找不到任何想要运行的线程时,它只会在忙等待中结束。