104

Qual è la differenza tra:Qual è il vantaggio dell'uso di async con MVC5?

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

e:

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

vedo che il codice MVC ha ora asincrona, ma qual è la differenza. Si danno prestazioni migliori rispetto agli altri? È più facile eseguire il debug dei problemi con uno rispetto all'altro? Devo apportare modifiche ad altri controller per la mia applicazione per aggiungere Async?

+0

Nella stragrande maggioranza delle situazioni non vi è alcun beneficio serio per l'utilizzo async in MVC, tuttavia ci sono molti aspetti negativi –

risposta

153

Le azioni asincrone sono utili solo quando si eseguono operazioni associate I/O come le chiamate server remote. Il vantaggio della chiamata asincrona è che durante l'operazione di I/O, non viene utilizzato alcun thread di lavoro ASP.NET. Ecco come funziona il primo esempio:

  1. Quando una richiesta raggiunge l'azione, ASP.NET preleva un thread dal pool di thread e avvia l'esecuzione.
  2. Viene invocato il metodo IdentityManager.Authentication.CheckPasswordAndSignIn. Questa è una chiamata bloccante -> durante l'intera chiamata il thread di lavoro viene messo a repentaglio.

Ed ecco come funziona la seconda chiamata:

  1. Quando una richiesta raggiunge l'azione, ASP.NET prende un thread dal pool di thread e inizia l'esecuzione di esso.
  2. Si chiama IdentityManager.Authentication.CheckPasswordAndSignInAsync che restituisce immediatamente. Una porta di completamento I/O è registrata e il thread di lavoro ASP.NET viene rilasciato nel pool di thread.
  3. In seguito al completamento dell'operazione, viene segnalata la porta di completamento I/O, un altro thread viene estratto dal pool di thread per terminare la restituzione della vista.

Come si può vedere nel secondo caso i thread di lavoro ASP.NET vengono utilizzati solo per un breve periodo di tempo. Ciò significa che ci sono più thread disponibili nel pool per servire altre richieste.

Quindi, per concludere, utilizzare le azioni asincrone solo quando all'interno è presente una vera API asincrona. Se fai una chiamata bloccante all'interno di un'azione asincrona, ne stai uccidendo l'intero beneficio.

+0

Informazioni sulla sincronizzazione del contesto. Non sarà un tale sovraccarico che non si vogliano usare azioni asincrone? "Il sovraccarico di un metodo asincrono che in realtà viene eseguito in modo asincrono dipende interamente dal fatto che sia necessario cambiare i thread utilizzando SynchronizationContext.Post. Se lo fa , il sovraccarico è dominato dal cambio di thread che viene eseguito mentre riprende il fatto che il significa che il l'attuale SynchronizationContext fa una grande differenza. " (Async in C# 5.0, 2012, Alex Davies) – annemartijn

+1

@Darin Perché è così importante rilasciare il thread principale? I thread sono limitati? – Omtechguy

+1

@Omtechguy yes Richiesta I thread hanno un certo limite –

1

Normalmente, una singola richiesta HTTP viene gestita da un singolo thread, rimuovendo completamente quel thread dal pool fino a quando non viene restituita una risposta. Con la TPL, non sei vincolato da questo vincolo. Qualsiasi richiesta che arriva inizia una continuazione con ogni unità di calcolo necessaria per calcolare una risposta in grado di eseguire su qualsiasi thread nel pool. Con questo modello, è possibile gestire molte più richieste simultanee rispetto a ASP.Net standard.

Se è qualche nuova attività che verrà generata o meno, e se dovrebbe essere attesa o meno. Pensa sempre a quei 70 ms, che è di ca. il massimo tempo che ogni chiamata al metodo dovrebbe prendere. Se è più lungo, la tua interfaccia utente probabilmente non si sentirà molto reattiva.

0

Nelle applicazioni Web che vedono un numero elevato di richieste simultanee all'avvio o che hanno un carico esplosivo (dove la concorrenza aumenta all'improvviso), rendere tali chiamate di servizio Web in modo asincrono aumenterà la reattività dell'applicazione. Una richiesta asincrona richiede lo stesso tempo per elaborare una richiesta sincrona. Ad esempio, se una richiesta effettua una chiamata al servizio Web che richiede due secondi per il completamento, la richiesta impiega due secondi se viene eseguita in modo sincrono o asincrono.Tuttavia, durante una chiamata asincrona, un thread non viene bloccato dal rispondere ad altre richieste mentre attende la prima richiesta di completamento. Pertanto, le richieste asincrone impediscono l'accodamento delle richieste e la crescita del pool di thread quando vi sono molte richieste simultanee che invocano operazioni a esecuzione prolungata.