Asynchronous controller blocks requests in ASP.NET MVC through jQuery

I just started using AsyncController in my project to take care of some lengthy reports. It would seem ideal at the time when I could start the report, and then perform several other actions, waiting for it to return and fill the elements on the screen.

My controller looks something like this. I tried to use the thread to perform a long task that I hoped the controller would release to get more requests:

public class ReportsController : AsyncController { public void LongRunningActionAsync() { AsyncManager.OutstandingOperations.Increment(); var newThread = new Thread(LongTask); newThread.Start(); } private void LongTask() { // Do something that takes a really long time //....... AsyncManager.OutstandingOperations.Decrement(); } public ActionResult LongRunningActionCompleted(string message) { // Set some data up on the view or something... return View(); } public JsonResult AnotherControllerAction() { // Do a quick task... return Json("..."); } } 

But what I find is that when I call LongRunningAction with a jQuery ajax request, any subsequent requests I make after that support it and are not processed until the LongRunningAction completes. For example, call LongRunningAction, which takes 10 seconds, and then call AnotherControllerAction, which is less than a second. AnotherControllerAction simply waits for the LongRunningAction to complete before returning the result.

I also checked jQuery code, but it is all the same if I specifically set "async: true":

 $.ajax({ async: true, type: "POST", url: "/Reports.aspx/LongRunningAction", dataType: "html", success: function(data, textStatus, XMLHttpRequest) { // ... }, error: function(XMLHttpRequest, textStatus, errorThrown) { // ... } }); 

Right now, I just have to assume that I am using it incorrectly, but I hope one of you guys can clear my mental block!

+23
javascript jquery c # asp.net-mvc-2
May 28 '10 at 8:59
source share
2 answers

There are two problems here. Firstly, your controller is not asynchronous. Twisting a ThreadPool thread to do the job usually has worse performance characteristics than just doing everything from the action method itself, since you still take the ThreadPool resources from ASP.NET (which just uses the CLR ThreadPool), and you're now forcing the CLR and OS to manipulate the threads. See http://msdn.microsoft.com/en-us/library/ee728598.aspx#choosing_synchronous_or_asynchronous_action_methods for more details. Basically, this connection boils down to the fact that if you cannot use the I / O completion ports for your asynchronous operations, you are unlikely to see improved performance.

The second problem is that ASP.NET MVC is blocking the session for all requests. Several requests during the same session will always be serialized, because otherwise the user session may become damaged if one controller writes to the session, because the other controller is trying to read it. See http://forums.asp.net/t/1501623.aspx for context and workaround. MVC 2 Futures has a way to disable this lock; it can also be included in MVC 3. See https://blogs.msdn.com/b/rickandy/archive/2009/12/17/session-less-mvc-controller.aspx for more details.

+30
May 28 '10 at 18:07
source share

Essentially the problem is this. HttpContext.Session because it is blocked, if you write something to a session in your AsyncController, you should avoid it and use this.HttpContext.Application - this will solve the problem, I had the same problem and try us

+3
Jul 18 '11 at 19:28
source share



All Articles