2015-04-15 6 views
7

Как мне заставить мои методы jquery вызывать мой контроллер mvc и мой контроллер mvc, чтобы одновременно выполнять 2 вещи?async jquery call to async mvc controller

Код jquery is doint fine. Он просто называет методы и продолжает двигаться, как я этого хочу.

$(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"); 
     } 
    }); 

Мой C# код с другой стороны, не делать две вещи одновременно:

[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); 
    } 

Комбинированный вызов должен принимать только немного больше, чем 10 секунд, если это будет сделано правильно, но теперь его берет двойной.

Нужно ли мне создать новый поток для звонков? Или это делается автоматически приложением?

EDIT: enter image description here

+0

Как проверить, что на стороне сервера не делать вещи параллельно? Является ли время между началом первого вызова «Hello1» и завершением «Hello2» более 20 секунд? MVC Framework автоматически управляет потоками, каждый запрос получает свой собственный поток. – drax

+0

Я не уверен, что понимаю, что вы имеете в виду. Я могу видеть в моей консоли i chrome, что вызовы hello1 и hello2 вызываются одновременно. Но я также вижу, что он отличается от 10 секунд с момента их возвращения. Вы можете увидеть это в моем изображении, которое я добавил в редактировании. –

+0

Да, это именно то, что я хотел знать. Обычно в этом сценарии используется состояние сеанса. Проверьте эту статью: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/ – drax

ответ

12

На основе изображения консоли Chrome проблема возникает в SessionState. По умолчанию, когда приложение использует SessionState, среда ASP обрабатывает запросы от одного пользователя последовательно (чтобы предотвратить переменные сеанса от потенциального повреждения).

Для случаев, когда вы хотите включить параллельную обработку запросов для одного пользователя (и не нужно обновлять сеанс), вы можете использовать атрибут SessionState на контроллере.

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

Более подробную информацию можно найти, например, здесь: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/

+0

Но что, если мне нужно установить некоторые sessionvariables в моем контроллере? Это не сработает, если у меня есть sessionstate readonly? Есть ли другой способ сделать это, чтобы я мог изменять значения моих переменных сеанса? :) –

+0

Насколько я знаю, вам нужно решить, как обновлять сеанс и параллельные запросы. Вы либо должны использовать какое-то другое хранилище для данных (база данных, cookie, cache, ..) или знать, что запросы на действия, которые обновляют сеанс, будут обрабатываться последовательно. – drax

1

Вы не вызывая await в методе GetSlowstring, поэтому она синхронно блокирует поток с Thread.Sleep(10000);. Для целей тестирования, вы можете попробовать заменить эту строку кода с Task.Delay методом (см MSDN article for this method):

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

enter image description here

+0

они все еще не выполняют задачи одновременно. И теперь для завершения первого требуется 20 секунд, а 30 для второго вместо 10 и 20, как и раньше. –

+0

@DanielGustafsson показывает одно и то же время для обоих запросов в Chrome на моей стороне. См. Изображение выше. – Eadel

+0

Также, как упоминалось в комментарии drax, каждый запрос получает свой собственный поток, поэтому даже вызовы без 'async' -' await' вернутся через 10 секунд.Преимущество их использования заключается в том, что поток не висит, ожидая завершения длинного вызова. – Eadel

0

Как о создании двух задач в контроллере MVC?

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

Task.WaitAll(t1,t2); 
+0

thats good idé ! Но моя проблема в том, что у меня есть разные вызовы из моего jquery, и они вызывают два разных метода в моем контроллере. В реальном коде может случиться так, что я не хочу вызывать оба метода, но только один. Поэтому ждать обоих методов будет просто задержка в этом случае. –

+0

Тогда просто используйте простой параметр перечисления в запросе, чтобы различать: обе задачи, только task1, только задача 2. –