3

我最近对我的一个 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 的用途。无论如何,我的问题是为什么会这样?

4

1 回答 1

1

通过异步调用委托,您可以将工作移至线程池。你还是烧一根线。你一无所获,表现不佳。

当您可以触发真正的异步 IO 时,异步最有意义。

于 2013-01-24T20:34:55.437 回答