Why is AsyncController stopping my server?

I recently made some (rather trivial) changes to one of my ASP.NET MVC3 controllers and changed one of the activities to an asynchronous activity. I basically took a code that looks like this:

public ActionResult MyAction(BindingObject params){
    // use HttpWebRequest to call an external API and process the results
}

      

And turned it into code that looks like this:

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
}

      

This seems to be okay, when I test it locally by calling MyAction, the breakpoints in each of the methods are triggered when I expect them and ultimately return the expected result.

I would expect this change to improve performance under heavy load at best, because now my worker threads are not eaten up, expecting HttpWebRequest to call an external API, and at worst there will be no effect.

Before pushing this change, my CPU usage averaged around 30% and my W3SVC_W3WP Active Requests. The server is Win Server 2008 R2 and the MVC site receives about 50 requests per second.

When this change is clicked, the processor starts to run to 90-100% and the W3SVC_W3WP active request counter slowly increases until it reaches a maximum of 5000 and stays there. The website becomes completely unresponsive (either timed out or "Service Unavailable" error discarded).

My guess is that I am either doing the AsyncController incorrectly, or missing some additional configuration, or requiring me to just not understand what the AsyncController should be used for. Anyway, my question is why is this happening?

+3


source to share


1 answer


With an async call to a delegate, you push work to the thread pool. You are still burning the thread. You get nothing and lose productivity.



Async mostly makes sense when you can initiate true async IO.

+1


source







All Articles