2015-04-15 11 views
7

Wie bekomme ich meine jquery Methoden, um meine MVC-Controller und mein MVC-Controller zu tun, um 2 Dinge gleichzeitig zu tun?async jquery Aufruf an async mvc Controller

Der jquery-Code ist nicht in Ordnung. Es ruft nur die Methoden an und geht so weiter, wie ich es möchte.

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

Mein C# -Code auf der anderen Seite wird zwei Dinge auf einmal nicht tun:

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

Der kombinierte Anruf nur ein wenig mehr als 10 Sekunden in Anspruch nehmen soll, wenn es richtig gemacht wird, aber es jetzt nimmt das Doppelte.

Muss ich einen neuen Thread für die Anrufe erstellen? Oder wird das automatisch vom Apppool gemacht?

EDIT: enter image description here

+0

Wie überprüfen Sie, dass Server-Seite ist nicht Dinge parallel zu tun? Ist die Zeit zwischen dem ersten Aufruf von 'Hello1' und dem Ende von' Hello2' größer als 20 Sekunden? MVC Framework verwaltet Threads automatisch für Sie, jede Anfrage erhält einen eigenen Thread. – drax

+0

Ich bin mir nicht sicher, ob ich verstehe, was Sie meinen. Ich kann in meiner Konsole sehen, dass die Anrufe für hallo1 und hallo2 gleichzeitig aufgerufen werden. Aber ich kann auch sehen, es unterscheidet sich 10 Sekunden von, wenn sie zurückkehren. Sie können dies in meinem Bild sehen, das ich in der Bearbeitung hinzugefügt habe. –

+0

Ja, genau das wollte ich wissen. Üblicher Fehler in diesem Szenario ist Sitzungsstatus. Überprüfen Sie diesen Artikel: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/ – drax

Antwort

12

Basierend auf dem Bild der Chrome-Konsole ist das Problem in SessionState. Wenn die Anwendung SessionState verwendet, verarbeitet das ASP-Framework standardmäßig Anfragen von einzelnen Benutzern seriell (um zu verhindern, dass Sitzungsvariablen möglicherweise beschädigt werden). Wenn Sie die parallele Verarbeitung von Anforderungen für einzelne Benutzer aktivieren möchten (und keine Sitzung aktualisieren müssen), können Sie das Attribut SessionState auf dem Controller verwenden.

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

Weitere Details finden Sie hier zum Beispiel zu finden: http://www.stefanprodan.com/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/

+0

Aber was, wenn ich einige Sitzungsvariablen in meinem Controller einstellen muss? Das funktioniert nicht, wenn ich den Sitzungsstatus nur gelesen habe? Gibt es eine andere Möglichkeit, es zu tun, so dass ich die Werte meiner Sessionvariablen ändern kann? :) –

+0

Soweit ich weiß, müssen Sie zwischen der Aktualisierung der Sitzung und parallelen Anforderungen entscheiden. Sie müssen entweder einen anderen Speicher für Daten verwenden (Datenbank, Cookie, Cache, ..) oder wissen, dass Anfragen für Aktionen, die die Sitzung aktualisieren, seriell verarbeitet werden. – drax

1

Sie sind nicht await in Ihre Methode aufrufen GetSlowstring, so dass er sich synchron blockiert den Thread mit Thread.Sleep(10000);. Zu Testzwecken können Sie versuchen, diese Codezeile mit Task.Delay Methode (siehe MSDN article for this method) zu ersetzen:

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

enter image description here

+0

sie machen immer noch nicht die Aufgaben gleichzeitig. Und jetzt dauert es 20 Sekunden für den ersten und 30 für den zweiten statt 10 und 20 wie zuvor. –

+0

@DanielGustafsson es zeigt die gleiche Zeit für beide Anfragen in Chrome auf meiner Seite. Siehe das Bild oben. – Eadel

+0

Auch, wie im Kommentar von drax erwähnt, bekommt jede Anfrage ihren eigenen Thread, so dass auch Aufrufe ohne 'async' -' wait' in 10 Sekunden zurückkommen.Der Vorteil, sie zu verwenden, besteht darin, dass der Thread nicht hängt, während er darauf wartet, dass der lange Anruf beendet wird. – Eadel

0

Wie über das Erstellen von zwei Aufgaben in den MVC-Controller?

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

Task.WaitAll(t1,t2); 
+0

das ist eine gute Idee ! Aber mein Problem ist, dass ich verschiedene Anrufe von meinem Jquery habe und sie zwei verschiedene Methoden in meinem Controller aufrufen. Im realen Code könnte es vorkommen, dass ich nicht beide Methoden sondern nur eine aufrufen möchte. Also warten beide Methoden wird nur eine Verzögerung in diesem Fall sein. –

+0

Dann verwenden Sie einfach einen einfachen enum Parameter in der Anfrage, um zu unterscheiden zwischen: beiden Aufgaben, nur task1, nur Aufgabe 2. –