Async and Await in ApiController Post

14

我仍然不太清楚在.net 4.5中异步和等待的概念。到目前为止,我认为我理解了await:

  1. 将(右侧)函数放在一个单独的线程上。
  2. 将执行返回到当前函数的调用者
  3. 但是保留当前函数剩余代码的其余部分“托管”,直到等待(异步)函数完成。

如果我有误,请纠正我。因此,如果以上是正确的,我卡在了要将ApiController的Post函数设置为async:

[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)的人。但是由于await让return Request.CreateResponse(HttpStatusCode.Created, obj);被“扣押”了,所以我还没有HttpResponseMessage对象。

在这个简单的例子中,调用会立即返回给客户端(也就是客户端JS网站或移动应用程序)吗?如果是这样,那么它会返回201、400、500(最好不要),还是其他代码?

2个回答

27
除了Stephen的回答,我需要指出几点。
首先,控制器中的异步并不会使用户体验异步。用户必须等待SomeReallyLongRunningTaskAsync()的时间。[那么我们为什么要使用异步?请参见下一点]
此外,如果SomeReallyLongRunningTaskAsync()是CPU绑定的,则不应以异步模式调用它。在服务器场景中使用异步的主要原因是将CLR线程释放回池中,以便IO完成端口(IOCP)可以处理剩余部分-直到IO工作完成,然后返回线程池。这将防止ASP.NET场景中常见的线程饥饿问题
IOCP仅在IO绑定情况下使用,例如:
  • 从/写入文件
  • 访问数据库或
  • 访问外部Web服务或WCF服务

有很多在线资源可以解释各个方面。如果我可以推荐的话,本书的第二章是一个优秀的资源,它可以给出关于Web API中异步操作的连贯理解。


15

将函数(在其右侧)放在单独的线程上。

不是的。 async 不会启动新线程。我有一个async intro可能会对您有所帮助。

Post 将完成执行并将控制返回给调用 myApiController.Post(obj) 的人。但我还没有 HttpResponseMessage 对象

正确。

在上面的简单示例中,调用会立即返回到客户端(即客户端 JS 网站或移动应用程序)吗?

不是的。ASP.NET MVC 4.5 看到您返回的是 Task<HttpResponseMessage> 而不是 HttpResponseMessage,因此它将等待直到您的 Task 完成(在您的 async Post 方法的末尾)才发送响应。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接