Web API 中的异步等待控制流

Posted

技术标签:

【中文标题】Web API 中的异步等待控制流【英文标题】:Async Await control flow in Web API 【发布时间】:2021-09-19 17:26:17 【问题描述】:
webcontroller 
         async Task<ActionResult<string>> doSomething() 
            var stringResult = await doSomethingAsync();
            return stringResult;
         

这里的控制流是什么?在到达 doSomething() 方法调用后,控制器是否会向客户端返回虚拟响应(ActionResult),或者控件会保留在 Web 控制器中并将 stringResult 返回给客户端?考虑 doSomething() 正在执行一些可能需要更多时间才能完成的网络密集型任务。如果可能的话,任何人都可以向我解释一下吗?提前致谢!

【问题讨论】:

【参考方案1】:

控制器是否会向客户端返回虚拟响应(ActionResult) 到达 doSomething() 方法调用或控件保留在 Web 控制器中并将 stringResult 返回给客户端后

doSomething 方法完成之前,它不会向客户端返回任何内容。

考虑 doSomething() 正在执行一些网络密集型任务 可能需要更多时间才能完成

在这种情况下,您将在客户端超时。

您必须启动后台作业。返回任务已启动的客户端。然后以某种方式告诉客户任务已完成。

另一个信息来源:Long running task in WebAPI

【讨论】:

感谢您的解释。考虑我已经使用 Task 在后台线程中安排了作业。运行,我已将任务和任务的操作 id 放在服务器端以从客户端检查状态(考虑我已经暴露了另一个 url 并且使用操作 id 客户端可以检查状态)。那么就不需要从控制器返回 Task> 了,对吧?我可以简单地返回 ActionResult。我的理解正确吗? 是的,在控制器中返回任务不是规则。但如果控制器使用其他异步 API - 那么控制器方法必须是异步的。【参考方案2】:

我推荐阅读我写的一篇关于 how async works on ASP.NET 的文章。

控制器会在到达doSomething()方法调用后向客户端返回虚拟响应(ActionResult)还是控制留在Web控制器中并将stringResult返回给客户端?

doSomethingAsync 返回一个未完成的任务时,则the await in doSomething will also return an incomplete task。然后 ASP.NET 运行时(异步)在发送响应之前等待该任务完成。

await 在 ASP.NET 中让给线程池;它does not yield to the client。

【讨论】:

对不起斯蒂芬。我无法理解你的说法。 然后 ASP.NET 运行时(异步)在发送响应之前等待该任务完成 doSomething() 返回一个不完整的任务,该任务当前由后台线程执行。假设后台任务将在 50 秒内完成。现在变量 stringResult 包含未完成的任务。你的意思是控制器会等到返回的不完整完成(收到不完整的任务后等待50秒)还是会返回不完整的任务响应(如工作开始)? @Jawahar_GCT:控制器向 ASP.NET 运行时返回一个不完整的任务。 ASP.NET 运行时(调用控制器的东西)将等待任务完成,然后再向客户端发送任何响应。在旁注中,there is no background thread.

以上是关于Web API 中的异步等待控制流的主要内容,如果未能解决你的问题,请参考以下文章

模型绑定不适用于 asp.net 核心 Web api 控制器操作方法中的 Stream 类型参数。(即使使用自定义流输入格式化程序)

nodejs中的异步流程序控制nsync

使用 ASP.NET Web API,控制器如何返回使用 DotNetZip 库压缩的流图像集合?

postgreSQL数据库同步流复制和异步流复制控制

javascript Node.js模式:异步控制流

RxSwift - 执行控制流会导致异步操作被执行两次