2015-04-15 32 views
7

Come faccio a ottenere i miei metodi jquery per chiamare il mio controller mvc e il mio controller mvc per fare 2 cose allo stesso tempo?chiamata jQuery asincrona al controller mvc asincrono

Il codice jquery va bene. Chiama solo i metodi e continua così come voglio.

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

mio codice C# d'altra parte non sta facendo due cose alla volta:

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

La chiamata combinato dovrebbe prendere solo un po 'più di 10 secondi se è fatto correttamente, ma ora prende il doppio.

Devo creare un nuovo thread per le chiamate? O è fatto automaticamente dal pool di app?

EDIT: enter image description here

+0

Come si fa a verificare, quel lato server non sta facendo le cose in parallelo? L'intervallo tra l'avvio della prima chiamata a 'Hello1' e la fine di' Hello2' è maggiore di 20 secondi? Il framework MVC gestisce i thread automaticamente, ogni richiesta ha il suo thread. – drax

+0

Non sono sicuro di capire cosa intendi. Posso vedere nella mia console i chrome che le chiamate per hello1 e hello2 vengono chiamate contemporaneamente. Ma posso anche vederlo differisce di 10 secondi dal loro ritorno. Puoi vedere questo nella mia immagine che ho aggiunto nella modifica. –

+0

Sì, questo è esattamente quello che volevo sapere. L'impronta consueta in questo scenario è lo stato di sessione. Controlla questo articolo: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/ – drax

risposta

12

In base all'immagine della console di Chrome, il problema è in SessionState. Per impostazione predefinita, quando l'applicazione utilizza SessionState, il framework ASP elabora le richieste da un singolo utente in modo seriale (per evitare che le variabili di sessione vengano danneggiate).

Per i casi in cui si desidera abilitare l'elaborazione parallela di richieste per singolo utente (e non è necessario aggiornare la sessione) è possibile utilizzare l'attributo SessionState sul controller.

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

Maggiori dettagli possono essere trovati per esempio qui: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/

+0

Ma cosa succede se ho bisogno di impostare alcune variabili di sessione nel mio controller? Questo non funzionerà se ho lo stato di sessione a sola lettura? C'è un altro modo per farlo in modo che io possa modificare i valori delle mie variabili di sessione? :) –

+0

Per quanto ne so, devi decidere tra l'aggiornamento della sessione e le richieste parallele. È necessario utilizzare una diversa memoria per i dati (database, cookie, cache, ..) o essere consapevoli che le richieste di azioni che aggiornano la sessione verranno elaborate in serie. – drax

1

Non sta chiamando await nel metodo GetSlowstring, quindi è sincrono blocca il filo con Thread.Sleep(10000);. A scopo di verifica, si può provare a sostituire questa riga di codice con Task.Delay metodo (vedi MSDN article for this method):

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

enter image description here

+0

non eseguono ancora le attività contemporaneamente. E ora ci vogliono 20 secondi per il primo a completare e 30 per il secondo invece di 10 e 20 come prima. –

+0

@DanielGustafsson mostra lo stesso tempo per entrambe le richieste in Chrome dalla mia parte. Guarda l'immagine qui sopra. – Eadel

+0

Inoltre, come accennato nel commento da drax, ogni richiesta riceve il proprio thread, quindi anche le chiamate senza 'async' -' await' ritorneranno in 10 secondi.Il vantaggio di utilizzarli è che il thread non è sospeso mentre attende il completamento della lunga chiamata. – Eadel

0

ne dite di creare due compiti nel controller MVC?

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

Task.WaitAll(t1,t2); 
+0

questo è un buon idé ! Ma il mio problema è che devo chiamare diverse dal mio jquery e stanno chiamando due metodi diversi nel mio controller. Nel codice reale potrebbe succedere che non voglio chiamare entrambi i metodi, ma solo uno. Quindi, attendere entrambi i metodi sarà solo un ritardo in quel caso. –

+0

Quindi basta usare un semplice parametro enum nella richiesta per distinguere tra: entrambe le attività, solo task1, solo task 2. –

Problemi correlati