9

How do i get my jquery methods to call my mvc controller and my mvc controller to do 2 things at the same time?

The jquery code is doint fine. It just calls the methods and keep on going as i want it to.

 $(document).ready(function () {
    console.log("1");
    getADsad();
    console.log("2");
    lala();
    console.log("3");
});
    function getADsad() {
        $.ajax({
            url: '/Configurator/Configure/Hello1',
            type: 'POST',
            dataType: 'json',
            success: function (data) {
                console.log(data + "hello1");
            }
        });
    }

function lala() {
    $.ajax({
        url: '/Configurator/Configure/Hello2',
        type: 'POST',
        dataType: 'json',
        success: function (data) {
            console.log(data + "hello2");
        }
    });

My C# code on the other hand is not doing two things at a time:

    [HttpPost]
    public async Task<LoginViewModel> Hello1()
    {
        var str = await GetSlowstring();
        return str;
    }

    [HttpPost]
    public async Task<LoginViewModel> Hello2()
    {
        var str = await GetSlowstring();
        return str;
    }

    public async Task<LoginViewModel> GetSlowstring()
    {
        await Task.Delay(10000);
        LoginViewModel login = new LoginViewModel();
        login.UserName = "HejsN";
        return await Task.FromResult(login);
    }

The combined call should take just a little more then 10 seconds if it is done correctly but now it takes the double.

Do i need to create a new thread for the calls? Or is this done automatically by the apppool?

EDIT: enter image description here

5
  • How do you verify, that server side is not doing things in parallel? Is time between you initiate first call to Hello1 and end of Hello2 greater than 20 seconds? MVC framework manages threads for you automatically, every request gets its own thread. Commented Apr 15, 2015 at 7:16
  • Im not sure i understand what you mean. I can see in my console i chrome that the calls for hello1 and hello2 is called the same time. But i can also see it differs 10 seconds from when they return. You can see this in my image i added in the edit. Commented Apr 15, 2015 at 7:25
  • Yes, this is exactly what I wanted to know. Usual culprint in this scenario is Session State. Check this article: stefanprodan.com/2012/02/… Commented Apr 15, 2015 at 7:31
  • Thanks @drax that helped! The sessionstate made the trick :) Commented Apr 15, 2015 at 7:44
  • I created answer with little more details, please accept it, so this question would be marked as answered. Commented Apr 15, 2015 at 7:59

3 Answers 3

14

Based on image of Chrome console, problem is in SessionState. By default, when application uses SessionState, ASP framework processes requests from single user serially (to prevent session variables from potential corruption).

For cases, when you want to enable parallel processing of requests for single user (and do not need to update session) you can use SessionState attribute on controller.

 [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]

More details can be found for example in here: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/

Sign up to request clarification or add additional context in comments.

2 Comments

But what if i need to set some sessionvariables in my controller? That won't work if i have sessionstate readonly? Is there another way to do it so that i can change the values of my sessionvariables?:)
As far as I know, you have to decide between updating session and parallel requests. You either have to use some different storage for data (database, cookie, cache, ..) or be aware, that requests for actions that update session will be processed serially.
1

You are not calling await in your method GetSlowstring, so it synchronously blocks the thread with Thread.Sleep(10000);. For testing purposes, you can try to replace this line of code with Task.Delay method (see MSDN article for this method):

public async Task<string> GetSlowstring()
{
    await Task.Delay(10000);
    return "hejsan";
}

enter image description here

5 Comments

they still don't do the tasks at the same time. And now it takes 20 sec for the first to complete and 30 for the second instead of 10 and 20 as before.
@DanielGustafsson it shows the same time for both requests in Chrome on my side. See the image above.
Also, as mentioned in the comment by drax, each request gets its own thread, so even calls without async - await will return in 10 seconds. The benefit of using them is that the thread is not hanging while waiting for the long call to be completed.
But how come i get different result :S My calls returns after 20 and 30 seconds which makes no sense at all :S
Ok, Drax comment about the article made the trick :) But thanks anyway!:)
0

How about creating two tasks in the MVC controller?

var t1 = new Task(() => { /*The slow task 1 */ });
var t2 = new Task(() => { /*The slow task 2 */});

Task.WaitAll(t1,t2);

2 Comments

thats a good idé! But my problem is that i have to different calls from my jquery and they are calling two different methods in my controller. In the real code it might happen that i don't want to call both the methods but just one. So await both methods will just be a delay in that case.
Then just use a simple enum parameter in the request to differentiate between: both tasks, only task1, only task 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.