异步任务(异步/等待)如何在.Net 4.5中运行?
一些示例代码:
private async Task<bool> TestFunction()
{
var x = await DoesSomethingExists();
var y = await DoesSomethingElseExists();
return y;
}
第二个await
语句是立即执行还是在第一个await
返回后执行?
答案 0 :(得分:51)
await
暂停该方法,直到操作完成。因此,第二个await
将在第一个await
返回后执行。
有关详细信息,请参阅我的async
/ await
intro或official FAQ。
答案 1 :(得分:15)
在第一次await返回后执行。如果这件事让您感到困惑,请尝试使用断点 - 新的异步模式完全支持它们。
想象一下它会是这样的:
var x = await GetSomeObjectInstance();
var y = await GetSomeObjectInstance2(x);
某处可能会出现NullReferenceException,因此第一个等待必须先返回。否则,x
将为null / undefined或其他。
答案 2 :(得分:13)
方法调用仍将按顺序发生,就像&#34;常规&#34;,无需等待的方法调用一样。等待的目的是它将当前线程返回到线程池,而等待的操作运行并执行任何操作。
这在高性能环境中尤其有用,例如Web服务器,其中给定请求在整个线程池的给定线程上处理。如果我们没有等待,那么处理请求的给定线程(以及它的所有资源)仍在使用&#34;正在使用&#34; db / service调用完成时。这可能需要几秒钟或更长时间,尤其是对于外部服务呼叫。
现在在流量较低的网站上,这不是一个大问题,但在高流量网站中,所有这些请求线程的成本只是坐在那里,什么也不做,在使用中&#34;等待其他进程(如返回的db / service调用)可能是一种资源负担。
我们最好将线程释放回工作池,以允许它为其他请求执行其他有用的工作。
一旦db / service调用完成,我们就可以中断线程池并要求一个线程继续从它停止的位置处理该请求。此时,重新加载请求的状态,并继续调用方法。
因此,在使用await时,在每个请求的基础上,从用户的角度来看,请求仍将花费相同的时间 ...加上一个微小的微笑更多的转换开销。
但总的来说,在所有用户的所有请求中,事情似乎对所有用户都更有效,因为Web服务器(在这种情况下)运行效率更高,资源利用率更高。也就是说它要么排队等待免费线程处理请求的请求,因为等待返回它们,或者我们不必购买更多硬件因为我们使用相同数量的硬件,效率更高,以获得更高的吞吐量。
尽管如此,尽管您在默认模板和许多文档中看到的内容都存在转换成本,但您不应该盲目地使用等待每一次调用。它只是一种工具,就像它所拥有的所有工具一样。如果转换成本不低于同步完成通话的成本,那么您就不应该使用等待。