任务等待呼叫误解

时间:2017-11-14 21:21:57

标签: c# async-await

任何人都可以向我解释这有什么意义吗?这是我在另一篇文章中回答的问题(Does await new Task(async () => Actually halt execution until finished?),我并没有真正理解评论的一部分......

  

异步等待 - 等待 - 等待任务完成。那是   为什么它被称为“等待”。

     

它是异步的,因为如果任务未完成则等待   返回调用者并在此线程上执行其他工作,直到   任务完成,此时等待的工作是   计划执行。

     

确保您了解await是任务的操作员。它不是   呼叫的呼叫约定。任何等待类型的表达都可以   期待已久的;不要陷入相信await打电话的陷阱   异步。被调用的方法已经是异步的;任务   返回是等待的东西。

它是如何“等待任务完成”但同时“返回给调用者并做其他工作”?

谢谢!

后续:

我已经看到了响应,那么在下面的伪代码示例中会发生什么?哪个命令实际发生在哪个任务?

await new Task(async () =>
{
    //Do stuff 1
    Thread.Sleep(10000);
}

EventLog.Write("Do Stuff 2");

await new Task(async () =>
{
    //Do stuff 3
    Thread.Sleep(10000);
}

将“Do Stuff 1”执行,然后等待,然后“Do Stuff 2”会发生,然后“Do Stuff 3”?或者“Do Stuff 1”执行然后立即“Do Stuff 2”然后“Do Stuff 3”?

1 个答案:

答案 0 :(得分:3)

并非所有工作都需要CPU或线程。

想象一下,您正在向Web服务发出HTTP请求。或者从磁盘或网络位置流式传输文件。在这些情况下,请求由另一个硬件组件处理,例如网络适配器或磁盘控制器。

如果网络存在延迟,并且需要很长时间才能获得响应,该怎么办?你可以坐在那里阻止,等待回应。或者您可以利用这段时间做其他事情。

这是asyncawait非常有用的地方。当你await一个正在进行I / O的方法(例如磁盘或网络)时,它基本上是在说“当这个任务完成时请告诉我”。然后你将返回调用者,这样你就可以做其他工作(可能是CPU绑定,也许是I / O绑定)。

当您等待的任务完成时,然后运行await语句之后的其余方法。这被称为延续 - 在await语句时捕获本地状态,它只是在它停止的地方继续。

我听到的一个很好的比喻就是做早餐。假设你正在喝杯咖啡和烤面包。煮沸水壶需要2分钟。你可以站在那里等待水壶煮沸,然后煮咖啡和烤面包。或者你可以开始煮沸的任务,去做吐司,然后当你听到吹口哨的水壶,你的“制作咖啡”任务从它停止的地方继续。哪个更有效率?

在您的示例中,您将按以下顺序获得以下内容:

  • 等待10秒(做东西1)
  • 写入事件日志(Do stuff 2)
  • 等待10秒(做东西3)

我们不会继续通过每个await来电,直到您等待的Task完成为止。在这种情况下,您正在等待async Task,因此它实际上是Task<Task>(因为异步委托本身使用Task)。但我认为外await打开了Task并且当最外面的Task完成时,会计划继续。