web-dev-qa-db-fra.com

Quel est l'avantage d'utiliser async avec MVC5?

Quelle est la différence entre:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

et:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

Je vois que le code MVC a maintenant async, mais quelle est la différence. Est-ce que l'un donne de bien meilleures performances que l'autre? Est-il plus facile de déboguer des problèmes avec l'un qu'avec l'autre? Devrais-je modifier d'autres contrôleurs pour que mon application ajoute Async?

117
user1943020

Les actions asynchrones ne sont utiles que lorsque vous effectuez des opérations liées aux E/S, telles que les appels de serveur distant. L'avantage de l'appel asynchrone est que, pendant l'opération d'E/S, aucun thread de travail ASP.NET n'est utilisé. Alors, voici comment fonctionne le premier exemple:

  1. Lorsqu'une demande frappe l'action, ASP.NET prend un thread du pool de threads et commence à l'exécuter.
  2. La méthode IdentityManager.Authentication.CheckPasswordAndSignIn est invoquée. Il s'agit d'un appel bloquant -> pendant tout l'appel, le thread de travail est compromis.

Et voici comment fonctionne le deuxième appel:

  1. Lorsqu'une demande frappe l'action, ASP.NET prend un thread du pool de threads et commence à l'exécuter.
  2. Le IdentityManager.Authentication.CheckPasswordAndSignInAsync est appelé et revient immédiatement. Un port d'achèvement d'E/S est enregistré et le thread de travail ASP.NET est publié dans le pool de threads.
  3. Plus tard, lorsque l'opération est terminée, le port d'achèvement d'E/S est signalé, un autre thread est tiré du pool de threads pour terminer le retour de la vue.

Comme vous pouvez le constater dans le deuxième cas, les threads de travail ASP.NET ne sont utilisés que pendant une courte période. Cela signifie qu'il y a plus de threads disponibles dans le pool pour répondre à d'autres demandes.

Pour conclure, utilisez les actions asynchrones uniquement lorsque vous avez une véritable API asynchrone. Si vous passez un appel bloquant dans une action asynchrone, vous en perdez tout le bénéfice.

162
Darin Dimitrov

Normalement, une seule requête HTTP serait traitée par un seul thread, supprimant complètement ce thread du pool jusqu'à ce qu'une réponse soit renvoyée. Avec la TPL, vous n'êtes pas lié par cette contrainte. Toute demande reçue entame une continuation avec chaque unité de calcul requise pour calculer une réponse capable de s'exécuter sur n'importe quel thread du pool. Avec ce modèle, vous pouvez gérer beaucoup plus de demandes simultanées qu'avec ASP.Net standard.

S'il s'agit d'une nouvelle tâche qui sera générée ou non, et si elle doit être attendue ou non. Pensez toujours à ces 70 ms, ce qui correspond à env. le max. le temps que n'importe quel appel de méthode devrait prendre. Si c'est plus long, alors votre interface ne sera probablement pas très sensible. 

2

Dans les applications Web qui voient un grand nombre de demandes simultanées au démarrage ou ont une charge en rafale (où la simultanéité augmente soudainement), rendre ces appels de service Web asynchrones augmentera la réactivité de votre application. Le traitement d’une demande asynchrone nécessite le même temps qu’une demande synchrone. Par exemple, si une demande effectue un appel de service Web qui nécessite deux secondes, la demande prend deux secondes, qu'elle soit exécutée de manière synchrone ou asynchrone. Toutefois, lors d'un appel asynchrone, un thread n'est pas empêché de répondre à d'autres demandes pendant qu'il attend la fin de la première demande. Par conséquent, les demandes asynchrones empêchent la mise en file d'attente des demandes et la croissance du pool de threads lorsque de nombreuses demandes simultanées appellent des opérations de longue durée.

0
Muhammad Essa