tutorial net mvc entre diferencias await async asp c# asp.net asp.net-mvc-4 asynchronous async-await

net - web forms c#



¿Cuándo debo usar Async Controllers en ASP.NET MVC? (8)

¿Es bueno usar la acción asíncrona en todas partes en ASP.NET MVC?

Como es habitual en la programación, depende . Siempre hay una compensación cuando se va por un camino determinado.

async-await brilla en lugares donde sabe que recibirá solicitudes simultáneas para su servicio y desea poder escalar bien. ¿Cómo ayuda async-await con el escalado horizontal? En el hecho de que cuando se invoca una llamada asíncrona IO sincrónicamente , como una llamada de red o golpear su base de datos, el hilo actual responsable de la ejecución se bloquea esperando que finalice la solicitud. Cuando usa async-await , habilita el marco para crear una máquina de estado para usted que se asegura de que después de que se complete la llamada IO, su método continúe ejecutándose desde donde se quedó.

Una cosa a tener en cuenta es que esta máquina de estado tiene una sobrecarga sutil. Hacer que un método sea asincrónico no hace que se ejecute más rápido , y ese es un factor importante para comprender y un error que muchas personas tienen.

Otra cosa a tener en cuenta al usar async-await es el hecho de que es asíncrono todo el tiempo , lo que significa que verá asíncrono penetrar en toda su pila de llamadas, de arriba a abajo. Esto significa que si desea exponer API síncronas, a menudo se encontrará duplicando una cierta cantidad de código, ya que la sync y la sync no se mezclan muy bien.

¿Debo usar palabras clave asíncronas / en espera cuando quiero consultar la base de datos (a través de EF / NHibernate / otro ORM)?

Si elige seguir el camino del uso de llamadas IO asíncronas, entonces sí, async-await será una buena opción, ya que cada vez más proveedores de bases de datos modernos exponen el método asíncrono que implementa el TAP (Patrón Asíncrono de Tarea).

¿Cuántas veces puedo usar palabras clave en espera para consultar la base de datos de forma asincrónica en UN método de acción único?

Todos los que desee, siempre y cuando siga las reglas establecidas por su proveedor de base de datos. No hay límite para la cantidad de llamadas asíncronas que puede hacer. Si tiene consultas que son independientes entre sí y pueden realizarse simultáneamente, puede girar una nueva tarea para cada una y usar la tarea de await Task.WhenAll para esperar a que se completen ambas.

Tengo algunas preocupaciones al usar acciones asincrónicas en ASP.NET MVC. ¿Cuándo mejora el rendimiento de mis aplicaciones y cuándo no ?

  1. ¿Es bueno usar la acción asíncrona en todas partes en ASP.NET MVC?
  2. En cuanto a los métodos que se pueden esperar: ¿debo usar palabras clave asíncronas / en espera cuando quiero consultar una base de datos (a través de EF / NHibernate / otro ORM)?
  3. ¿Cuántas veces puedo usar palabras clave en espera para consultar la base de datos de forma asincrónica en un solo método de acción?

¿Es bueno usar la acción asíncrona en todas partes en ASP.NET MVC?

Es bueno hacerlo siempre que pueda utilizar un método asíncrono, especialmente cuando tiene problemas de rendimiento en el nivel de proceso de trabajo que ocurre con datos masivos y operaciones de cálculo. De lo contrario, no es necesario porque las pruebas unitarias necesitarán fundición.

En cuanto a los métodos que se pueden esperar: ¿debo usar palabras clave asíncronas / en espera cuando quiero consultar una base de datos (a través de EF / NHibernate / otro ORM)?

Sí, es mejor usar asíncrono para cualquier operación de base de datos como sea posible para evitar problemas de rendimiento a nivel de procesos de trabajo. Tenga en cuenta que EF ha creado muchas alternativas asíncronas para la mayoría de las operaciones, como:

.ToListAsync() .FirstOrDefaultAsync() .SaveChangesAsync() .FindAsync()

¿Cuántas veces puedo usar palabras clave en espera para consultar la base de datos de forma asincrónica en un solo método de acción?

El cielo es el limite


Como sabes, MVC admite controladores asíncronos y deberías aprovecharlo. En caso de que su Controlador realice una operación prolongada (puede ser una E / S basada en disco o una llamada de red a otro servicio remoto), si la solicitud se maneja de forma síncrona, el subproceso IIS está ocupado todo el tiempo. Como resultado, el hilo solo está esperando que se complete la operación larga. Se puede utilizar mejor atendiendo otras solicitudes mientras la operación solicitada en primer lugar está en progreso. Esto ayudará a atender más solicitudes concurrentes. Su servicio web será altamente escalable y no se encontrará fácilmente con el problema C10k . Es una buena idea usar async / await para consultas db. y sí, puede usarlos tantas veces como lo considere conveniente.

Eche un vistazo here para obtener excelentes consejos.


Mi experiencia es que hoy en día muchos desarrolladores usan async/await como predeterminado para los controladores.

Mi sugerencia sería, úsela solo cuando sepa que le ayudará .

La razón es que, como y otros ya mencionaron, puede introducir problemas de rendimiento, en lugar de resolverlos, y solo lo ayudará en un escenario específico:

  • Controladores de alto tráfico
  • Backend escalable

Mis 5 centavos:

  1. Use async/await si y solo si realiza una operación de E / S, como DB o servicio web de servicio externo.
  2. Siempre prefiera las llamadas asíncronas a DB.
  3. Cada vez que consulta la base de datos.

PD: Hay casos excepcionales para el punto 1, pero debe tener una buena comprensión de los aspectos internos asíncronos para esto.

Como ventaja adicional, puede hacer pocas llamadas IO en paralelo si es necesario:

Task task1 = FooAsync(); // launch it, but don''t wait for result Task task2 = BarAsync(); // launch bar; now both foo and bar are running await Task.WhenAll(task1, task2); // this is better in regard to exception handling // use task1.Result, task2.Result


Puede encontrar útil mi artículo de MSDN sobre el tema ; Tomé mucho espacio en ese artículo que describe cuándo debe usar async en ASP.NET, no solo cómo usar async en ASP.NET.

Tengo algunas preocupaciones al usar acciones asincrónicas en ASP.NET MVC. Cuando mejora el rendimiento de mis aplicaciones y cuándo no.

Primero, comprenda que async / await se trata de liberar hilos . En las aplicaciones GUI, se trata principalmente de liberar el hilo GUI para que la experiencia del usuario sea mejor. En aplicaciones de servidor (incluido ASP.NET MVC), se trata principalmente de liberar el hilo de solicitud para que el servidor pueda escalar.

En particular, no:

  • Haga que sus solicitudes individuales se completen más rápido. De hecho, se completarán (solo un poquito) más lentamente.
  • Regrese a la persona que llama / navegador cuando llegue a await . await solo "rendimientos" al grupo de subprocesos ASP.NET, no al navegador.

La primera pregunta es: ¿es bueno usar la acción asincrónica en todas partes en ASP.NET MVC?

Yo diría que es bueno usarlo donde sea que esté haciendo E / S. Sin embargo, puede no ser necesariamente beneficioso (ver más abajo).

Sin embargo, es malo usarlo para métodos vinculados a la CPU. A veces los desarrolladores piensan que pueden obtener los beneficios de async simplemente llamando a Task.Run en sus controladores, y esta es una idea horrible. Debido a que ese código termina liberando el subproceso de solicitud al tomar otro subproceso, por lo que no hay ningún beneficio (¡y de hecho, están tomando la penalidad de los conmutadores de subproceso adicionales)!

¿Debo usar palabras clave asíncronas / en espera cuando quiero consultar la base de datos (a través de EF / NHibernate / otro ORM)?

Podrías usar cualquier método que tengas disponible. En este momento, la mayoría de los principales jugadores admiten async , pero hay algunos que no. Si su ORM no admite async , no intente Task.Run en Task.Run ni nada de eso (ver arriba).

Tenga en cuenta que dije " podría usar". Si está hablando de ASP.NET MVC con un único back-end de base de datos, entonces (casi seguro) no obtendrá ningún beneficio de escalabilidad de async . Esto se debe a que IIS puede manejar muchas más solicitudes concurrentes que una sola instancia del servidor SQL (u otro RDBMS clásico). Sin embargo, si su back-end es más moderno (un clúster de servidores SQL, Azure SQL, NoSQL, etc.) y su back-end puede escalar y su cuello de botella de escalabilidad es IIS, entonces puede obtener un beneficio de escalabilidad de async .

Tercera pregunta: ¿cuántas veces puedo usar palabras clave en espera para consultar la base de datos de forma asincrónica en UN método de acción único?

Tantos como quieras. Sin embargo, tenga en cuenta que muchos ORM tienen una regla de una operación por conexión. En particular, EF solo permite una sola operación por DbContext; Esto es cierto si la operación es síncrona o asíncrona.

Además, tenga en cuenta la escalabilidad de su back-end nuevamente. Si está llegando a una única instancia de SQL Server y su IIS ya es capaz de mantener SQLServer a plena capacidad, duplicar o triplicar la presión sobre SQLServer no lo ayudará en absoluto.


async acciones async ayudan mejor cuando las acciones realizan algunas operaciones de E / S a la base de datos o algunas llamadas enlazadas a la red donde el subproceso que procesa la solicitud se detendrá antes de que reciba la respuesta de la llamada enlazada a la red o DB que acaba de invocar. Es mejor que use esperar con ellos y realmente mejorará la capacidad de respuesta de su aplicación (porque menos hilos de entrada / salida ASP se detendrán mientras espera la base de datos o cualquier otra operación como esa). En todas mis aplicaciones, cuando son necesarias muchas llamadas a DB, siempre las he envuelto en un método aceptable y lo he llamado con la palabra clave wait.


Los métodos de acción asincrónica son útiles cuando una acción debe realizar varias operaciones independientes de larga duración.

Un uso típico de la clase AsyncController son las llamadas de servicio web de larga duración.

¿Deben las llamadas de mi base de datos ser asíncronas?

El grupo de subprocesos de IIS a menudo puede manejar muchas más solicitudes de bloqueo simultáneas que un servidor de base de datos. Si la base de datos es el cuello de botella, las llamadas asincrónicas no acelerarán la respuesta de la base de datos. Sin un mecanismo de aceleración, el envío eficiente de más trabajo a un servidor de bases de datos abrumado mediante el uso de llamadas asincrónicas simplemente transfiere más carga a la base de datos. Si su DB es el cuello de botella, las llamadas asincrónicas no serán la bala mágica.

Debes echar un vistazo a las referencias 1 y 2

Derivado de los comentarios de @PanagiotisKanavos:

Además, asíncrono no significa paralelo. La ejecución asincrónica libera un hilo valioso del conjunto de subprocesos del bloqueo de un recurso externo, sin costo de complejidad o rendimiento. Esto significa que la misma máquina IIS puede manejar más solicitudes concurrentes, no es que se ejecute más rápido.

También debe considerar que las llamadas de bloqueo comienzan con un spinwait intensivo de CPU. Durante los momentos de estrés, el bloqueo de llamadas provocará retrasos crecientes y el reciclaje del grupo de aplicaciones. Las llamadas asincrónicas simplemente evitan esto