webentwicklung-frage-antwort-db.com.de

Warum ist dieser Web-API-Controller nicht gleichzeitig aktiv?

Ich habe einen Web-API-Controller mit der folgenden darin enthaltenen Methode:

public string Tester()
{
    Thread.Sleep(2000);

    return "OK";
}

Wenn ich es 10 Mal aufrufe (mit Fiddler), erwarte ich, dass alle 10 Aufrufe nach ~ 2 Sekunden zurückkehren. Die Anrufe kehren jedoch jeweils nach 2,4,8 ... 20 Sekunden zurück. Was hindert es daran, gleichzeitig ausgeführt zu werden? Wie behebe ich das?

Verhalten sich normale Controller genauso wie Web-API-Controller?

12
Elad Katz

Was Sie beschreiben, stimmt mit dem Standardverhalten des ASP.NET-Sitzungszustands überein und kann durch Deaktivieren in web.config behoben werden.

Der Zugriff auf den ASP.NET-Sitzungsstatus ist exklusiv pro Sitzung. Wenn zwei verschiedene Benutzer gleichzeitig Anforderungen stellen, wird der Zugriff auf jede separate Sitzung gleichzeitig gewährt. Wenn jedoch zwei gleichzeitige Anforderungen für dieselbe Sitzung gestellt werden (indem derselbe Wert für SessionID verwendet wird), erhält die erste Anforderung exklusiven Zugriff auf die Sitzungsinformationen. Die zweite Anforderung wird erst ausgeführt, wenn die erste Anforderung abgeschlossen ist. (Die zweite Sitzung kann auch Zugriff erhalten, wenn die ausschließliche Sperre für die Informationen freigegeben wird, da die erste Anforderung das Zeitlimit für die Sperre überschreitet.) Wenn der EnableSessionState-Wert in der @ Page-Direktive auf ReadOnly festgelegt ist, eine Anforderung für das schreibgeschützte Objekt Sitzungsinformationen führen nicht zu einer exklusiven Sperre der Sitzungsdaten. Nur-Lese-Anforderungen für Sitzungsdaten müssen jedoch möglicherweise noch auf eine durch eine Lese-/Schreibanforderung gesetzte Sperre warten, damit Sitzungsdaten gelöscht werden.

Quelle: Überblick über den ASP.NET-Sitzungsstatus

13
sisve

Ich glaube nicht, dass ich Ihre Frage beantworte, aber was ich hier schreiben möchte, ist zu groß für einen Kommentar.

Zunächst hat die ASP.NET-Web-API nichts mit dem Sitzungsstatus zu tun. Wenn die Sitzung mit der Web-API verwendet werden muss, muss sie explizit aktiviert werden.

Jetzt habe ich denselben API-Controller wie Sie und ich hosten ihn in IIS. Wenn ich gleichzeitige Anforderungen stelle, werden die Anforderungen parallel und nicht seriell ausgeführt. So habe ich von Fiddler getestet.

Zuerst machte ich ein GET für die API und wartete auf 200 Statuscode (Nr. 1 im linken Bereich von Fiddler). Dann wählte ich # 1 und drückte U, um die gleiche Anforderung neunmal uneingeschränkt abzuspielen. Damit habe ich 10 Anfragen im linken Bereich (# 1 bis # 10). Dann wählte ich alle 10 aus und drückte R, um alle zehn Anfragen parallel erneut auszugeben. Ich wählte dann die Anfragen 11 bis 20 im linken Bereich aus und ging zur Timeline-Registerkarte. Ich sehe diese Grafik.

PS. Ich habe die Web-API lokal getestet, übrigens.

enter image description here

Als Nächstes wollte ich die Zeitstempelanforderung so protokollieren, wie sie von der Aktionsmethode empfangen wurde. Also habe ich die Aktionsmethode geändert, um eine Zeichenfolge wie diese zurückzugeben.

public string Get()
{
    string ts = DateTime.Now.ToString("mm:ss.fff");
    Thread.Sleep(2000);
    return ts;
}

Ich habe folgendes bekommen.

00:43.795
00:43.795
00:45.812
00:44.517
00:43.795
00:43.795
00:45.515
00:43.795
00:43.795
00:43.795

Für mich bedeutet das, dass alle Anforderungen parallel laufen.

8
Badri

Sehen Sie sich diese Frage an, die relativ zu Ihrem Problem ist: Werden alle Webanforderungen parallel ausgeführt und asynchron behandelt?

Es sagt, dass:

Ein webApi-Dienst führt standardmäßig alle seine eingehenden Anforderungen in Parallel aus, jedoch nur, wenn die mehreren aktuellen Anforderungen (zu einem bestimmten Zeitpunkt ) Aus verschiedenen Sitzungen stammen. Das heißt, wenn ein einzelner Client Einige gleichzeitige Anforderungen an den Server sendet, werden alle Sequenziell ausgeführt und nicht gleichzeitig ausgeführt.

Um dieses Problem zu lösen, können Sie async-Methoden verwenden, wie hier beschrieben.

Im Allgemeinen müssen Sie Ihre Methode als asynchron deklarieren:

public async Task<MyObj> GetObj()
5
Mark Segal

Verwenden Sie stattdessen Folgendes:

public async Task<string> Tester()
{

    await Task.Delay(2000);
    return "OK";
}

Sehen Sie sich dies an, um den Unterschied zwischen Task.Delay vs Thread.Sleep zu erfahren, der http://social.technet.Microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task.) Blockiert -delay.aspx

0
Omar.Alani

Sie müssen den Session State irgendwo für Web Api aktiviert haben. Das Web-API ist standardmäßig unruhig und hat keine Sitzung. Überprüfen Sie den Abschnitt "global.asax Application_AuthenticateRequest" (hier aktiviere ich den Sitzungsstatus für Web Api). Finden Sie heraus, wo Sie Ihren Sitzungsstatus aktiviert haben, und setzen Sie ihn in den schreibgeschützten Modus, um Parallelität für Webmethoden mit Sitzungsstatus zu ermöglichen. Siehe diese Frage, die ähnlich ist: Web-API-Dienst - Wie werden die Anforderungen auf dem Server gleichzeitig ausgeführt?

Suchen Sie nach etwas wie diesem:

HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);

Ändern Sie es zu diesem:

HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
0