ApiController Post 中的异步和等待
Posted
技术标签:
【中文标题】ApiController Post 中的异步和等待【英文标题】:Async and Await in ApiController Post 【发布时间】:2013-10-18 19:57:48 【问题描述】:我仍然不太清楚 .net 4.5 中的 async 和 await 。到目前为止,我想我理解等待:
-
将函数(在其右侧)放在单独的线程上。
将执行返回给当前函数的调用者
但保留当前函数的其余代码“人质”,直到等待(异步)函数完成。
如果我误解了什么,请纠正我。所以,如果上述情况属实,我就会坚持使用我想要异步的 ApiController 的 Post 函数:
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody]MyObject obj)
myDataContext.MyObjects.InsertOnSubmit(obj);
myDataContext.SubmitChanges();
await SomeReallyLongRunningTaskAsync();
// obj would now have the new Id, which I'm really after.
return Request.CreateResponse(HttpStatusCode.Created, obj);
因此,如果我理解正确,Post 将完成执行并将控制权返回给调用 myApiController.Post(obj)
的任何人。但我还没有 HttpResponseMessage
对象,因为 await 持有 return Request.CreateResponse(HttpStatusCode.Created, obj);
"人质"。
在上面这个简单的例子中,调用是否会立即返回到客户端(即客户端 JS 网站或移动应用程序)?如果是这样,它会是 201、400、500(最好不要),其他?
【问题讨论】:
【参考方案1】:除了斯蒂芬的回答,我还需要指出一些事情。
首先,控制器中的异步不会使用户体验异步。只要SomeReallyLongRunningTaskAsync()
需要,用户就必须等待。 [那么我们为什么要做异步?看下一点]
另外,如果 SomeReallyLongRunningTaskAsync()
是 CPU 密集型的,那么你不应该在异步模式下调用它。在服务器场景中使用异步的主要原因是将 CLR 线程释放回池,以便 IO 完成端口 (IOCP)可以处理其余的 - 直到 IO 工作完成,然后返回线程池。这样可以避免 ASP.NET 场景中常见的 Thread Starvation 问题。
IOCP仅在IO绑定的情况下使用,例如:
读取/写入文件 访问数据库或 访问外部 Web 服务或 WCF 服务网上有大量资源可以解释各个方面。如果我可以插上一句,Chapter 2 of this book 是一个很好的资源,它提供了对 Web API 中异步的内聚理解。
【讨论】:
【参考方案2】:将函数(在其右侧)放在单独的线程上。
没有。 async
不会启动新线程。我有一个async
intro,你可能会觉得有帮助。
Post 将完成执行并将控制权返回给调用 myApiController.Post(obj) 的任何人。但我还没有 HttpResponseMessage 对象
正确。
在上面这个简单的例子中,调用是否会立即返回到客户端(即客户端 JS 网站或移动应用程序)?
没有。 ASP.NET MVC 4.5 看到您返回的是Task<HttpResponseMessage>
而不是HttpResponseMessage
,因此在您的Task
完成之前它不会发送响应(在您的async
Post
方法结束时)。
【讨论】:
以上是关于ApiController Post 中的异步和等待的主要内容,如果未能解决你的问题,请参考以下文章
将所有 POST 请求路由到单个 ApiController
如何在Web项目中给没有添加API核心组件添加APIController的帮助页HelpPage
转如何在Web项目中给没有添加API核心组件添加APIController的帮助页HelpPage