“异步一路走下去”:嗯,底部到底是什么?

时间:2017-01-03 07:50:21

标签: c# .net asynchronous async-await

我正在努力完全理解async - await,而我理解中的一个缺点就是看到“一路走下去”。我创建了一个async方法,它被另一个async方法等调用,一直到我用“UI”或“可以处理的Web服务器”等模糊术语理解的东西多个请求“。我如何用技术术语描述什么是“一直向下”?

让我们来看一个Web服务器的第二个例子。假设我有像

这样的控制器动作
[HttpGet]
public async Task<IHttpActionResult> GetRecords()
{
    var records = await repository.GetRecordsFromDbAsync();
    return Ok(records);
}

在.NET源代码中哪里可以找到“一直向下”的代码,可以异步调用它?

5 个答案:

答案 0 :(得分:17)

短语“async all down down”有点误导,因为它通常指的是一旦你使用异步方法,你需要一直使用异步方法 up (或返回,具体取决于您的心理形象) - 从您的异步方法到其来电者,然后是来电者的来电,等等,一直回来。

您的示例显示了一个公开async任务的WebApi / MVC控制器。 async链中的下一步是WebApi / MVC基础结构,它接收HTTP GET请求,将其映射到控制器,并将调用分派给控制器的方法。此基础结构async可识别,这意味着它知道正确调用async控制器方法并且await其结果返回HTTP响应。

至于如何实现基础架构,我并不是特别了解,也不关心 - 我知道ASP.NET Web服务支持async Task控制器,这对我来说已经足够了。

答案 1 :(得分:13)

一直是Win32 API。在该级别,异步I / O通过OVERLAPPED个对象完成,并且可警告等待,例如WaitForMultipleObjectsEx

答案 2 :(得分:6)

GetRecordsFromDbAsync是一种异步方法,因此您的顶级异步方法(由支持异步的ASP.NET Web服务器调用)只是将其异步性移交给下一级别。

一直到GetRecordsFromDbAsync或其后代实际调用调用堆栈中的最后一个异步方法。在那里它可能会变成本机,它会注册一个I / O中断或其他在读取文件,处理Web请求等时被调用的内容。

答案 3 :(得分:4)

从您的问题中不清楚您在哪里找到了引用,或者在什么情况下使用它。然而,&#34; async一直向下&#34;通常被理解为意味着您不应该在单个逻辑操作中在同步和异步方法之间来回切换。

如果要异步完成某些事情,它应该始终异步,在所有级别 - 因此,&#34;一直向下&#34; (以及)层次结构/调用堆栈/等。换句话说,在异步代码中的任何一点执行同步阻塞调用都没有意义,因为它根本就不是异步的。

来自.NET Parallel Programming团队的博客文章"Should I expose synchronous wrappers for asynchronous methods?"

  

完全异步

     

这里的要点是,在将异步API包装为同步API时需要非常小心,好像你不小心,你可能遇到真正的问题。如果您发现自己认为需要从期望同步调用的东西调用异步方法(例如,您正在实现一个具有同步方法的接口,但为了实现该接口,您需要使用仅限于此的接口异步暴露),首先确保它是真正的,真正必要的;虽然将“sync over async”包装起来似乎更为便利,而不是重新检测这个或那个代码路径从上到下是异步的,但如果可能的话,重构往往是更好的长期解决方案。

至于您在.NET源代码MSalters has already answered this中可以找到的问题。从根本上说,.NET API将调用Windows操作系统提供的系统级API。它们执行异步I / O,并在调用者完成后发出信号。但是,您并不需要了解这在技术层面如何运作;这就是抽象的全部要点。

答案 4 :(得分:3)

每个过程编程语言都是一系列函数/过程调用,其中一个函数/过程调用另一个。可以使用调用图see Wikipedida for a starting point for call graphs来表示从一个过程到另一个过程的这个调用序列。这些图表通常显示从顶部开始并一直到底部的程序调用序列。

我快速生成了ASP .NET MVC应用程序的部分调用图表。该图仅是ASP .NET MVC应用程序的部分表示,因为它省略了诸如操作系统(例如Windows),Web服务器(例如IIS)和ASP .NET的各种组件的初始接收请求之类的内容。它负责处理HTTP请求,因为它通过ASP .NET请求处理管道。出于本讨论的目的,可以省略这些事项。虽然值得注意的是它们会位于调用图的顶部,因为它们处理处理HTTP请求的初始阶段,最终,在某些时候ASP .NET最终会调用控制器的动作。

正如您在图中看到的,我已经表示了将由ASP .NET作为异步操作调用的控制器的操作。在调用图的左侧是一系列异步过程调用。最终它会到达您问题主题的方框。

与“一直向下”这个概念一致的问题的答案是“我是一个异步方法”。这种异步方法有什么作用?那么,这取决于你想做什么?如果您正在读取或写入文件,那么它是一个异步调用来读取或写入文件。你在做数据库查询吗?然后调用是一个执行该查询的异步方法。考虑到这一点,我猜你可以说通常底层的是一个设备驱动程序方法,它以异步方式执行IO访问。虽然它很容易成为您希望执行的长时间运行的计算绑定异步操作,例如处理图像或视频文件。

这里也值得注意调用图的右侧。虽然通常您可能希望一直调用异步方法,但此调用图的右侧分支显示您根本不需要在底部调用异步方法。 enter image description here