我最近对我的一个 ASP.NET MVC3 控制器进行了一些(相当微不足道的)更改,并将其中一个操作更改为异步操作。基本上我采用了如下代码:
public ActionResult MyAction(BindingObject params){
// use HttpWebRequest to call an external API and process the results
}
并将其变成如下所示的代码:
private delegate ActionResult DoMyAction(BindingObject params);
public void MyActionAsync(BindingObject params){
AsyncManager.OutstandingOperations.Increment();
var doMyAction = new DoMyAction(MyAction);
doMyAction.BeginInvoke(params, MyActionCallback, doMyAction);
}
private void MyActionCallback(IAsyncResult ar){
var doMyAction = ar.AsyncState as DoMyAction;
AsyncManager.Parameters["result"] = doMyAction != null ? doMyAction.EndInvoke(ar) : null;
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult MyActionCompleted(ActionResult result){
return result;
}
private ActionResult MyAction(BindingObject params){
// use HttpWebRequest to call an external API and process the results
}
这似乎工作正常,当我在本地调用 MyAction 对其进行测试时,每个方法中的断点都会在我期望的时候触发,并最终返回预期的结果。
我预计此更改最多可以提高重负载下的性能,因为现在我的工作线程没有被占用,等待 HttpWebRequest 调用外部 API,最坏的情况是根本没有效果。
在推动此更改之前,我的服务器的 CPU 使用率平均约为 30%,而我的 W3SVC_W3WP Active Requests perfmon stat 徘徊在 10-15 左右。服务器是 Win Server 2008 R2,MVC 站点每秒收到大约 50 个请求。
在推动此更改后,CPU 的使用率会达到恒定的 90-100%,并且 W3SVC_W3WP 活动请求计数器会缓慢增加,直到达到最大值 5000 并保持在那里。网站变得完全没有响应(超时或出现“服务不可用”错误)。
我的假设是我要么错误地实现了 AsyncController,缺少一些额外的配置,要么只是误解了 AsyncController 的用途。无论如何,我的问题是为什么会这样?