Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 4.5 Async Ajax call not working

I have a slow running action on a controller that I've converted to the new Async method. It now runs much faster, however any jQuery Ajax calls to it return the following string,

System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult]

instead of waiting for the async to complete.

What am I doing wrong here? I've followed every example I can find and this isn't rocket science to implement.

Pretty much followed what is outlined in this video

http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2287

And this link too

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4#CreatingAsynchGizmos

I understand that the Async doesn't change HTTP, but what I was expecting was for the long runnning Ajax call to work in the background, and then return to the user the result when it was finished. This would then free up the server to process additional ajax calls instead of blocking them.

Update:

Here is the javascript code

function doWork(options){
    return $.ajax("/getData", {
                    contentType: 'text/json',
                    async: true,
                    success: $.proxy(options.callback, options.scope),
                    error: function (jqXHR, textStatus, error) {
                        options.callback.apply(options.scope, [error, textStatus, jqXHR]);
                    }
                });
}

And here is my controller action in C#

[HttpGet]
[AsyncTimeout(60000)]
public async Task<ActionResult> GetData()
        {
            RestResponse<Data> response = new RestResponse<Data>();

            try
            {
                Data result = null;

                await Task.Factory.StartNew(() =>
                {
                    result = ServerImpl.RetrieveData();
                });

                response.Value = result;
                response.HttpStatusCode = 200;
            }
            catch (Exception ex)
            {
                response.HttpStatusCode = 500;
                response.Value = null;
            }

            return Json(response, JsonRequestBehavior.AllowGet);
        }
like image 783
Matt Avatar asked May 16 '13 19:05

Matt


2 Answers

The problem is that your server side action uses ASP.NET Session which is characterized by not being thread-safe. As a consequence, ASP.NET queues parallel requests from the same session and executes them sequentially. Having a RESTful API relying on session is a very bad design and IMHO should be rearchitectured so that it doesn't rely on state.

like image 121
Darin Dimitrov Avatar answered Oct 11 '22 08:10

Darin Dimitrov


I think I had the same problem where using Session was preventing my requests running concurrently. Since I'm not modifying session already, decorating my controller with this attribute allows the requests to run concurrently now.
[SessionState(SessionStateBehavior.ReadOnly)]

like image 30
Cody H Avatar answered Oct 11 '22 07:10

Cody H