为什么AsyncController使我的服务器停止运转?

时间:2013-01-24 20:10:15

标签: c# asp.net-mvc

我最近对我的一个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 Active Requests计数器缓慢增加,直到达到最大值5000并保持在那里。该网站完全没有响应(超时或提供“服务不可用”错误)。

我的假设是我正在错误地实现AsyncController,缺少一些所需的额外配置,或者可能只是误解了AsyncController应该用于什么。无论如何,我的问题是为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

通过异步调用委托,您可以将工作移动到线程池。你仍然刻录一个线程。你什么也得不到,而且表现松散。

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