ApiController Post中的Async和Await

Mic*_*uso 14 c# asynchronous async-await asp.net-web-api

我仍然不太清楚isync并等待.net 4.5.到目前为止,我想我明白等待:

  1. 将函数(在其右侧)放在一个单独的线程上.
  2. 将执行放回当前函数的调用者
  3. 但保持当前函数的代码"hostage"的其余部分,直到等待(异步)函数完成.

如果我误解了什么,请纠正我.所以,如果以上情况属实,我会遇到一个我想要异步的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);

}
Run Code Online (Sandbox Code Playgroud)

因此,如果我正确理解这一点,Post将完成执行并将控制权交还给任何人myApiController.Post(obj).但是,HttpResponseMessage由于等待举行return Request.CreateResponse(HttpStatusCode.Created, obj);"人质",我还没有这个对象.

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

Ali*_*tad 27

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

首先,控制器中的异步不会使用户体验异步.用户必须等待一段SomeReallyLongRunningTaskAsync()时间.[那我们为什么要做异步?看下一点]

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

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

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

在线提供大量资源并解释各个方面.如果我可以插一个插件,本书的第2章是一个很好的资源,可以让我们对Web API中的Async有一个统一的理解.


Ste*_*ary 14

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

async不启动一个新的线程.我有一个你可能会觉得有帮助的async介绍.

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

正确.

在上面这个简单的例子中,调用会立即返回客户端(即客户端JS网站还是移动应用程序)?

没有.ASP.NET MVC 4.5看到你正在返回Task<HttpResponseMessage>而不是HttpResponseMessage,所以在Task完成之前(在async Post方法结束时)它不会发送响应.