ApiController Post中的Async和Await

时间:2013-10-10 21:07:50

标签: c# asynchronous asp.net-web-api async-await

我还不太清楚异步并等待.net 4.5。到目前为止,我想我明白了等待:

  1. 将函数(右侧)放在一个单独的线程上。
  2. 将执行返回给当前函数的调用者
  3. 但保留当前函数代码“hostage”的其余部分,直到等待(异步)函数完成。
  4. 如果我误解了某些事情,请纠正我。所以,如果上述情况属实,我会遇到一个我想要异步的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对象,因为等待return Request.CreateResponse(HttpStatusCode.Created, obj);“人质”。

    在上面这个简单的例子中,调用会立即返回客户端(即客户端JS网站还是移动应用程序)?如果是这样,它会是201,400,500(最好不是),其他吗?

2 个答案:

答案 0 :(得分:26)

除了斯蒂芬的回答,我还需要指出一些事情。

首先,控制器中的异步不会使用户体验异步。只要SomeReallyLongRunningTaskAsync()占用,用户就必须等待。 [那我们为什么要做异步?见下一点]

此外,如果SomeReallyLongRunningTaskAsync()受CPU限制,则不应以异步模式调用它。在服务器方案中使用Async的主要原因将CLR线程释放回池,以便 IO完成端口(IOCP)可以处理其余的 - 直到IO工作完成,然后返回到线程池。这样可以防止ASP.NET场景中常见的线程饥饿问题。

IOCP仅在 IO绑定情况下使用 ,例如:

  • 读取/写入文件
  • 访问数据库或
  • 访问外部Web服务或WCF服务

在线提供大量资源并解释各个方面。如果我可以插一个插件,Chapter 2 of this book是一个很好的资源,可以让我们对Web API中的Async有一个统一的理解。

答案 1 :(得分:14)

  

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

没有。 async无法启动新主题。我有async intro你可能会觉得有帮助。

  

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

正确。

  

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

没有。 ASP.NET MVC 4.5发现您正在返回Task<HttpResponseMessage>而不是HttpResponseMessage,因此在Task完成之前(async结束时,它不会发送回复} Post方法)。