我最近对我的一个 ASP.NET MVC3 Controller 做了一些(相当微不足道的)更改,并将其中一个操作更改为异步操作。基本上我采用了如下代码:
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 事件请求 perfmon 统计数据徘徊在 10-15 左右。服务器是 Win Server 2008 R2,MVC 站点每秒接收大约 50 个请求。
在插入这一变化后,CPU 的使用率飙升至 90-100%,并且 W3SVC_W3WP 事件请求计数器缓慢增加,直到达到最大值 5000 并保持在那里。该网站变得完全没有响应(超时或出现“服务不可用”错误)。
我的假设是我错误地实现了 AsyncController,缺少一些必需的额外配置,或者可能只是误解了 AsyncController 的用途。无论如何,我的问题是为什么会这样?
最佳答案
通过异步调用委托(delegate),您将工作移至线程池。你仍然烧线。您一无所获,性能也很差。
当您可以触发真正的异步 IO 时,异步最有意义。
关于c# - 为什么 AsyncController 会使我的服务器停止运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14509848/