web-dev-qa-db-fra.com

Pourquoi ce contrôleur d’API Web n’est-il pas concurrent?

J'ai un contrôleur API Web avec la méthode suivante à l'intérieur:

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

    return "OK";
}

Lorsque je l’appelle 10 fois (avec Fiddler), j’attends que les 10 appels soient renvoyés au bout de 2 secondes environ. Cependant, les appels reviennent après 2,4,8 ... 20 secondes, respectivement. Qu'est-ce qui l'empêche de fonctionner simultanément? Comment puis-je résoudre ce problème?

Les contrôleurs habituels ont-ils le même comportement que les contrôleurs Web-api?

12
Elad Katz

Ce que vous décrivez correspond au comportement par défaut de l'état de session ASP.NET et peut être résolu en le désactivant dans web.config.

L'accès à l'état de session ASP.NET est exclusif par session, ce qui signifie que si deux utilisateurs différents effectuent des demandes simultanées, l'accès à chaque session distincte est accordé simultanément. Toutefois, si deux demandes simultanées sont effectuées pour la même session (en utilisant la même valeur SessionID), la première demande obtient un accès exclusif aux informations de la session. La deuxième requête ne s'exécute qu'après la fin de la première requête. (La deuxième session peut également avoir accès si le verrou exclusif sur les informations est libéré car la première demande dépasse le délai de verrouillage.) Si la valeur EnableSessionState de la directive @ Page est définie sur ReadOnly, une demande de lecture seule Les informations de session n'entraînent pas de verrouillage exclusif des données de session. Cependant, les demandes en lecture seule pour les données de session peuvent encore attendre un verrou défini par une demande en lecture-écriture pour que les données de session soient effacées.

Source: Vue d'ensemble de l'état de session ASP.NET

13
sisve

Je ne pense pas répondre à votre question, mais ce que j'aimerais écrire ici est trop volumineux pour un commentaire.

Tout d’abord, l’API Web ASP.NET n’a rien à voir avec l’état de la session. En fait, si une session doit être utilisée avec une API Web, elle doit être explicitement activée.

Maintenant, j'ai le même contrôleur API que vous et je l’héberge dans IIS. Si je fais des demandes simultanées, les demandes sont exécutées en parallèle et non en série. Voici comment j'ai testé de Fiddler.

Tout d'abord, j'ai effectué une requête GET vers l'API et attendu 200 codes d'état (n ° 1 dans le volet gauche de Fiddler). Ensuite, j'ai sélectionné # 1 et appuyé sur U pour rejouer la même demande de manière inconditionnelle 9 fois. Sur ce, j'ai 10 demandes dans le volet de gauche (N ° 1 à 10). Ensuite, j'ai sélectionné les 10 et j'ai appuyé sur R pour réémettre les dix demandes en parallèle. J'ai ensuite sélectionné les demandes 11 à 20 dans le volet gauche et je suis allé à l'onglet Chronologie. Je vois ce graphique.

PS J'ai testé l'API Web fonctionnant localement, BTW.

enter image description here

Ensuite, je voulais enregistrer la demande d'horodatage telle que reçue par la méthode d'action. J'ai donc modifié la méthode d'action pour renvoyer une chaîne comme celle-ci.

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

J'ai eu le suivant.

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

Pour moi, cela signifie que toutes les demandes s'exécutent en parallèle.

8
Badri

Regardez cette question qui est relative à votre problème: Toutes les requêtes Web sont-elles exécutées en parallèle et gérées de manière asynchrone?

Il déclare que:

Un service webApi, par défaut, exécute toutes ses demandes entrantes en parallèle , Mais uniquement si les multiples demandes en cours (à une certaine Heure) proviennent de sessions différentes. Autrement dit, si un seul client Envoie plusieurs demandes simultanément au serveur, elles seront toutes Exécutées de manière séquentielle et ne seront pas exécutées simultanément.

Pour résoudre ce problème, vous pouvez utiliser des méthodes asynchrones, comme décrit ici .

En règle générale, vous devez déclarer votre méthode async, comme ceci:

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

Essayez d'utiliser ceci à la place:

public async Task<string> Tester()
{

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

Consultez cette section pour connaître la différence entre Task.Delay et Thread.Sleep, qui bloque http://social.technet.Microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task- delay.aspx

0
Omar.Alani

Vous devez avoir activé le Session State quelque part pour Web Api. L'API Web est reposante par défaut et n'a pas de session. Vérifiez votre section global.asax Application_AuthenticateRequest (c’est là que j’active l’état de session pour Web Api). Recherchez l'emplacement où vous avez activé l'état de session et définissez-le en mode lecture seule pour permettre le parallélisme des méthodes Web utilisant l'état de session. Voir cette question similaire: Service API Web - Comment exécuter simultanément les demandes sur le serveur

Cherchez quelque chose comme ça:

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

Changez-le en ceci:

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