Una entrada cortita y al grano, pero que te significará ahorrarte más de un dolor de cabeza y además programar como un pro, comencemos.
Para entender este concepto aplicaré una analogía con una situación cotidiana:
Imagina por un instante que te pones a hervir agua para servirte una taza de café, sí, ese café que tanto te gusta, dime tú, te quedas esperando todo ese tiempo mirando a la tetera a que termine? 🤔
Lo más probable es que no, cierto? tú aprovechas ese tiempo para hacer otras cosas y ya cuando suene la tetera entonces retomas lo otro y te sirves el café.
Eso mismo es lo que hace la programación asíncrona, hace uso de los llamados threads o hilos de ejecución del procesador para que puedas ejecutar más de un proceso a la vez en tu aplicación.
Si no trabajas con programación asíncrona quiere decir entonces que tu aplicación siempre trabajará sobre un mismo hilo de ejecución y esto significa un problema, no solo de rendimiento por cuellos de botella (lentitud por convergencia de procesos), sino también de seguridad y disponibilidad, ya que es probable que tu aplicación deje de funcionar o se "crashee" 😐 debido a la demanda de procesos en ejecución al mismo tiempo.
Ejemplo real
Tomemos como ejemplo el caso de un Web API, tenemos este método GET que nos devuelve un cliente por su Id:
[HttpGet("{id:int}", Name = "obtenerCliente")]
public async Task<ActionResult<ClienteDTO>> Get(int id)
{
var entidad = await context.Clientes.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
if (entidad == null)
return NotFound();
return mapper.Map<ClientesDTO>(entidad);
}
He resaltado las líneas donde se incluyen los operadores que hacen que un método sea asíncrono, como notamos para que un método lo sea, debemos declararlo con async y debe retornar algo así como una promesa de retorno, esto es un Task.
También incluímos el operador await, el propósito de este es el de indicarle al procesador que el proceso actual lo haga en el hilo actual y aperture otro hilo paralelo de forma que la aplicación siga funcionando en alguna otra petición y no se estanque, más adelante en el momento en que este proceso retorne la data entonces continúa.
Es mejor entender conceptos abstractos con situaciones que todos conocemos 😄
Buena práctica
Se dice que es buena práctica aplicar la programación asíncrona debido a que hay situaciones en las que no se tiene el control del proceso, por ejemplo:
- Llamadas a bases de datos, no sabemos cuanto tarde en devolvernos la data solicitada o en que termine de insertar los registros enviados, en resumen no tenemos control del servidor de base de datos.
- Cuando se trabaja con archivos, también no se tiene el control, puede que necesite permisos al sistema operativo o mil situaciones, dejar paralizada nuestra aplicación por esto sería mortal.
- Mejor control de los procesos, si no ejecutamos await por ejemplo, puede que nuestra aplicación quiera continuar en el mismo thread sin que haya terminado de traer la información de la base de datos, con esto se generan inconsistencias, también podría generar colisiones en las llamadas a la base de datos dejándola no disponible para algunos usuarios mientras que otros sí obtienen lo esperado.
- Mayor disponibilidad del sistema, ya que permite ejecutar múltiples acciones al mismo tiempo.
La programación asíncrona tiene un pequeño costo de rendimiento, pero es despreciable si se usa de manera adecuada.
Espero haber resuelto tus dudas, sin embargo aquí hay una entrada muy genial también, es del buen Felipe Gavilán échale un vistazo a su blog!
Si esta entrada te fascinó compártela en tus redes, pero sólo si te fascinó, si sólo te gustó no lo hagas 😂
Es muy importante que entiendas como funciona el bucle de evento. Por eso hemos utilizado un modelo grafico que deberias utilizar como modelo mental cuando utilices la programacion asincrona dirigida por eventos en tus aplicaciones. En este video comenzamos mostramos un ejemplo de codigo sincrono que degrada a la aplicacion, en este caso a la interfaz de usuario, debido a la ejecucion de funciones lentas en el hilo principal, y continuaremos modificandolo para evitar este problema. La modificacion consistira, como ya te habras imaginado, en convertir la parte de ejecucion lenta en asincrona.
Gracias por comentar, por su puesto me gustaría ver lo que hiciste, compártenos el video. Como regla general siempre un proceso que depende de agentes externos o tiene duración incierta como por ejemplo acceso a datos, o archivos, o consulta a API externas, debería ser asíncrono. Saludos.