ASYNC / AWAIT en C# - Programación ASÍNCRONA - Haz que tu aplicación sea más rápida utilizando Task

แชร์
ฝัง
  • เผยแพร่เมื่อ 19 ก.ย. 2024

ความคิดเห็น • 66

  • @NetMentor
    @NetMentor  4 ปีที่แล้ว +5

    Blog: www.netmentor.es/Entrada/programacion-asincrona
    Twitter: twitter.com/NetMentorTW

  • @PabloC-Dev
    @PabloC-Dev 10 หลายเดือนก่อน +2

    Este si explicó muy bien, like!!!...

  • @franciscoramos5378
    @franciscoramos5378 2 ปีที่แล้ว

    Muchas gracias y enhorabuena por tu trabajo. Es difícil encontrar en youtube trabajos de esta excelente calidad.

  • @williamprogramer4168
    @williamprogramer4168 4 ปีที่แล้ว +1

    muchas gracias al día de hoy no sabia el poder completo que tenia la clase Task, gracias por compartir tu conocimiento.

  • @cristiancalichio5335
    @cristiancalichio5335 2 ปีที่แล้ว +1

    Muchísimas gracias excelente explicación muy clara y precisa, justamente busqué para no liarla con unas dudas que me surgían. Realmente ayudan mucho tus videos y excelente material que tenés en el blog. 🦾
    Por la forma de explicar las cosas siempre un paso más allá con ejemplos claros de lo que podría pasar y por qué. Saludos desde Argentina.😀

  • @jose2608
    @jose2608 2 ปีที่แล้ว +1

    Buen video

  • @edgarrivera7636
    @edgarrivera7636 3 ปีที่แล้ว +2

    Justo el video que estaba buscando, bien explicado!!!

  • @RogerOspina
    @RogerOspina 2 ปีที่แล้ว

    Os amo !!!! ♥

  • @dangerosa01
    @dangerosa01 4 ปีที่แล้ว

    sos muy bueno explicando, se nota cuando alguien sabe de verdad

  • @leonelquiroga7648
    @leonelquiroga7648 2 ปีที่แล้ว +1

    Este tema me traia loco muchas gracias!!

  • @caterinanavarro3918
    @caterinanavarro3918 3 ปีที่แล้ว +1

    Es el primer video que veo de tu canal y me pareció de verdad que aporta mucho valor. Muchos se limitan a explicar algún concepto sin entrar mucho en detalle. Y me parece que está buenisimo que des estos tips de cuando lo podemos usar y cuando no, con ejemplos que representan un problema de la vida real. Ahora entiendo mejor como usar la programación asincróna. Muchas gracias por el aporte!

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      Gracias! Me alegro de que te guste, Si la verdad que cree el canal pensando en eso, en los casos de uso de la vida real. :)
      Un saludo

    • @caterinanavarro3918
      @caterinanavarro3918 3 ปีที่แล้ว

      @@NetMentor Genial! :) es muy buena la iniciativa, creo que aporta muchisimo
      Por otro lado, hay algo que me gustaría consultarte, entiendo que lo mejor es usar async siempre que se pueda. Ahora mismo arme una app simple dividida en varias capas (API, Services, Data y Models) y estoy usando Unit Of Work con EF Core. Todos los métodos y endpoints son async y tengo un await en cada uno. Mi duda es, supongamos que por ejemplo hago un request de un getall que tiene muchos datos, y de manera consecutiva hago otra solicitud. Ambos se ejecutarían en paralelo, verdad? o el segundo request esperaría a que termine el primero y eso haría que tarde más en ejecutar la acción?

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      cuando dices una request entiendo que te refieres a una llamada a la api verdad?
      sí, se ejecutaran en paralelo, pero, en ese escenario da igual que sea async o no, ya que .net es el que se encarga (automáticamente) de ejecutarlas en paralelo.
      Un saludo

    • @caterinanavarro3918
      @caterinanavarro3918 3 ปีที่แล้ว

      @@NetMentor Si, me referia a eso. Excelente! Muchas gracias :D

  • @erikomarmontescastro100
    @erikomarmontescastro100 3 ปีที่แล้ว +2

    Brutal, me ayudó mucho amigo

  • @senioralon3
    @senioralon3 2 ปีที่แล้ว

    Muy bueno!!! gracias

  • @reynaldo1x
    @reynaldo1x 3 ปีที่แล้ว +1

    Explicas muy bien y tu pagina excelente. se agradece!

  • @raulcanocorbera5873
    @raulcanocorbera5873 3 ปีที่แล้ว +1

    Excelente video muchas gracias saludos

  • @facundoarce758
    @facundoarce758 3 ปีที่แล้ว +1

    Buen video, me ayudo mucho.

  • @internationaltranslators159
    @internationaltranslators159 4 ปีที่แล้ว

    GRACIAS .... MUY BUENA EXPLICACION ... CORDIAL SALUDO.

  • @carlosmauriciorebolledosie6286
    @carlosmauriciorebolledosie6286 4 ปีที่แล้ว

    Excelente video. Muchas gracias por compartirlo

  • @franciscogamboahernandez8418
    @franciscogamboahernandez8418 3 ปีที่แล้ว +1

    Gracias, eres un crack!

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Gracias a ti!

  • @123karlytos
    @123karlytos 4 ปีที่แล้ว +2

    muy bueno

    • @NetMentor
      @NetMentor  4 ปีที่แล้ว

      Gracias, se agradece un montón :)

  • @YoungHWN
    @YoungHWN ปีที่แล้ว +1

    wowwww

  • @marioibanez1233
    @marioibanez1233 3 ปีที่แล้ว

    Enhorabuena por estas explicaciones y muchas gracias por compartir este conocimiento. Estoy incorporando el asyn en mis proyectos y me estan surgiendo dos incidencias. La primera es con los metodos ya creados con Async, el cual no me permite poner la palabra reservada await.
    Ej. csvReader lib
    var result = csv.GetRecordsAsync();

    await foreach (T f in csv.GetRecordsAsync())
    No se si es la manera correcta, el trabajar con IAsyncEnumerable o es mejor crear un Task.Run con el metodo sincrono GetRecords.
    En otro lugar la consola.writeline no se como utilizarla correctamente porque no se me ven los mensajes en estoso metodos asincronos. Gracias.

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      Hola!
      El error que comentas de que no te permite poner la palabra async es muy extraño, necesitaria mas datos, o ver el error. async/await fue introducido en C# 5 que si no me equivoco es .NET Framework 4.5 así que si tu código es una versión anterior no podrás utilizar async/await.
      Suponiendo que este no es tu problema, necestiaré algo mas de información, por ejemplo si es una app de consola, web, escritorio, etc.
      Pero otro error común puede ser que falte la `Task` englobando al tipo de retorno en el método, más o menos como lo siguiente:
      public async Task GetResults(){
      await foreach (T item in csv.GetRecordsAsync())
      yield return item;
      }
      deberia de funcionarte sin darte ningún error (creo vaya, no lo he probado) .
      Luego sí, debes trabajar con IAsyncEnumerable, fue introducido el año pasado junto con c#8 y la verdad que funciona bastante bien, yo lo utilzo en algunos proyectos y sin problemas. Todo lo que sea, dejar al código trabajar por si solo con los hilos son buenas noticias 😂
      Un saludo!

  • @CAGUANET121
    @CAGUANET121 4 ปีที่แล้ว +3

    Excelente tema, me despejo muchas dudas. Gracias por compartir conocimiento.
    Por otro lado quería preguntarte que arquitectura manejas en el proyecto y si tienes repos en GitHub. Manejas el patron united of work?
    Nuevamente gracias.

    • @NetMentor
      @NetMentor  4 ปีที่แล้ว +2

      Gracias, es siempre agradable ver que lo que haces ayuda :).
      Sobre a GitHub tener tengo, y es donde subo los contenidos de youtube, pero para proyectos personales la verdad no lo use hasta entonces, así que solo tengo una librería que moví desde vsts. github.com/ElectNewt/Programacion-avanzada/tree/master/programacion_asincrona_ejemplo
      y desde que tengo el canal, pues apenas tengo tiempo de hacer proyectos personales, más allá de los videos/blogs que al final me llevan unas cuantas horas cada uno.
      Respecto a la arquitectura, en la oficina, que es donde tenemos "recursos ilimitados" tenemos una arquitectura 90% serverless en AWS basada en eventos, mayoritariamente SQS y Lambdas, por supuesto utilizamos buckets, EBL, etc pero la gran mayoría de la arquitectura son lamdas y SQS.
      Luego para los clientes tenemos una app web que contiene dentro amazon quicksight.(este es el 10% no serverless)
      En mi web, tengo una arquitectura simple con "MVC" lo pongo entre comillas porque al final el modelo son varias capas de lógica ya que utilizo mucha encapsulación, abstracción e interfaces. LA web es "pequeña" por lo que no hace falta microservices.
      Y finalmente sobe unit of work, Primero de todo especificar que utilizo Dapper orm para la base de datos, por lo que tenemos (tanto en la oficina como en mis proyectos personales) que escribir el SQL más o menos de forma manual.
      una vez dicho esto, lo que hago es abrir una transacción antes del primer insert y al final del último hacer un commit de la propia transacción.
      así en caso de que algo falle me evito tener que hacer un rollback (y es prácticamente lo mismo que unit of work).

  • @master1986a
    @master1986a 3 ปีที่แล้ว

    Excelente video! Te quería consultar, en el ejemplo de los resultados 1, 2 , etc. si alguna de esas tareas diera un error como podría identificarla? Gracias y un saludo!

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      Slatara la excepción indicandote donde, pero el tema es que el proceso "salta" este donde este. asi que deberas tratar todas las tasks como si todas huberan fallado y hacer un rollback en caso de que lo neeistes;
      si por ejemplo son 3 inserts en la bbdd, y uno falla, probablemente esten relacionados, así que tendrás que hacer el rollback de todo.
      Pero no hay forma de comproarlo de forma "automática", o sea puedes comprobar una a una si esta completada con valores
      espero que se entienda, un saludo!

  • @lucianootegui4778
    @lucianootegui4778 3 ปีที่แล้ว

    Excelente video como siempre NetMentor!
    Te queria hacer dos consultas el cual todavia me generan dudas:
    Primero, cual seria la mejor manera de manejar la excepciones cuando hay Asyncronismo de por medio, entiendo y estuve leyendo otros comentarios, el cual vi que no recomendas los try catch, pero no termino de entender de que manera es mejor manejarla. Hacer un Middleware de control de excepciones?
    Pasa que, si tenes consultas a un sql server, no estas un poco obligado a poner un try catch por si salta algun sqlexception?
    No se si tendrás algun video que hable puramente y muestres ejemplos de manejo de excepciones con async y demás.
    La otra duda es, si yo tengo distintas apis que solo consultan datos a un sql server en donde van y traer información, o inserta información. En estos casos deberia de usar Asyncronismo desde la llamada a la bdd hasta el controlador no? Es decir, deberían ser puramente asyncronicos.
    Quiero destacar que en estos casos estaria ejecutando Stored Procedures cuando hago estas llamadas a la bdd.
    Muchas gracias de antemano!
    Saludos

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      Hola! para manejar las excepciones cuando hay asincronismo es igual que si no la hay, en eso no hay diferencia, respecto al try/cach, eso es únicamente si la quieres controlar, es muy común que si la bbdd esta caida, salte la excepción y al usuario lo mandes a /error o similar. si quieres volver a intentar hacer el proceso en 1 segundo o asi (royo una policy) si lo puedes poner en un try/cach pero hay librerias que ya implementan estas cosas.
      Respecto al middleware pues depende, puedes hacerte uno para controlar las excecpiones, pero va a ser únicamente para lo que le muestras al usuario, no en el funcionamiento como tal.
      Y respecto al punto dos si, todo uso de un proceso fuera de tu codigo (a una base de datos, al sistema de ficheros, otra API, etc) deben ser asíncronos.
      Un saludo!

    • @lucianootegui4778
      @lucianootegui4778 3 ปีที่แล้ว

      @@NetMentor buenísimo, muchas gracias por la respuesta! Saludos

  • @Santiago-er2ml
    @Santiago-er2ml 3 ปีที่แล้ว

    Muy buen video, tengo un problema servicio asíncrono que me corta la ejecución y no me tira ningún tipo de excepción, lo mas extraño es que regularmente lo hace al querer agregar un objeto al modelo (de entity framework) de base de datos. Osea, directamente corta la ejecución sin mas.

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Pues es raro, no tienes ningún error ni nada? Hace mucho que no toco EF pero puede ser el cancellation token, aún así sin más datos imposible :/
      Te pasa siempre o de forma aleatoria?

  • @renat3x2112
    @renat3x2112 3 ปีที่แล้ว

    Una consulta, en los métodos getarticulo, que usaste openasync, he visto en la documentación que hay también executereaderasync y varios métodos así, porque no lo usaste o en que casos es bueno utilizarlos? Gracias de antemano

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Hola! utilizo tanto OpenAsync para abrir la conexión y debemos llamar a este método en cada una de nuestras consultas.
      Y también utilizo ExecuteReaderASync() el cual abre un sqlDataReader que nos permite ir leyendo cada uno de los resultados uno a uno. (actua como un select en la base de datos)
      hace ya bastate que hice el vídeo, pero creo que ademas tambien utilizo ExecuteNonQueryAsync que es cuando tienes un insert/update/delete y no necesitas devolver los valores.
      Un saludo

  • @RaulLopez-ch5fl
    @RaulLopez-ch5fl 3 ปีที่แล้ว

    Muchas gracias por este aporte, de verdad se valora.
    Tengo una duda, espero me puedas ayudar, que tan recomendable es tener el try catch dentro de la tarea, en ocasiones lo utilizo así pero no estoy seguro si sea una buena practica.
    Una vez mas gracias, saludos!!!

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Hola! a que te refieres con tener el try catch dentro de una tarea? en un método que devuelve task/task?
      dependerá un poco de lo que haga el método en concreto
      yo por norma general no soy muy de poner try catch en el codigo, ya que las excepciones son eso, excepciones y si sabemos que una puede saltar, lo que tenemos es que implementar una validación que no salte. Algunas veces no es posbile (ciertos servicios, no tienen comprobar si x existe pero si crear, entonces para comprobar si existe tienes que crear y da una excepción), pero por norma general, en código propio, la recomendación es dejar que si hay una excepción salte y arreglar el problema.
      poner try catch por todas partes es poner parches, y en muchas empresas esta como norma/costumbre hacerlo y es una pena.
      un saludo.

    • @RaulLopez-ch5fl
      @RaulLopez-ch5fl 3 ปีที่แล้ว

      @@NetMentor gracias por tu pronta respuesta, voy a tomar en cuenta lo que comentas, saludos.

  • @maclaren33
    @maclaren33 3 ปีที่แล้ว

    Gracias buen video amigo. Solo hay algo q no entiendo. En el open async pusiste un await entonced hay q esperar q termine cual era la diferencia de utilizar el open

    • @maclaren33
      @maclaren33 3 ปีที่แล้ว

      osea await conexion.OpenAsync(); aqui esperamos que la conexion se abra para continuar pero si lo hubieramos dejado asi conexion.Open(); pasaba lo mismo, esto es lo uqe no entiendo

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว +1

      @@maclaren33 la cosa es qeu cuando utilizas async/await el hilo se puede utilizar para otras cosas (otros procesos) pero si lo haces con open se queda bloqueado hasta recibir la conexión.
      imagina que la base de datos tarda 10 segundos en darte el okey.
      con open la app se queda "enganchada" durante 10 segundos y con openasync simplemente haría otras cosas durante ese tiempo.
      Un saludo

    • @maclaren33
      @maclaren33 3 ปีที่แล้ว

      @@NetMentor muchas gracias

    • @maclaren33
      @maclaren33 3 ปีที่แล้ว

      @@NetMentor La última pregunta, comprendo el hilo se bloquearia, pero este hilo no es el hilo principal (ui) entonces los otros hilos no se bloqueara si utilizo open en lugar de open Async solo el hilo donde se está haciendo el open. Este hilo donde se está haciendo el open se bloqueara pero daría igual ya q no puedo hacer otra cosa mientras no obtengo la conexión. Los otros hilos así se bloque este hilo de conexión no les pasará nada. Gracias por la atención

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      @@maclaren33 eso ya depende de lo que hagas exactamente, y cuantos suuarios, con un par de usuarios en web, seguro que no, osea, en la web, por como funciona por detrás puedes hacer otras cosas (consultar , abrir otra página, etc) ;
      Pero si tienes miles de usuarios simultaienos, te interesa que nos se qeuden bloqueados, imagina que tienes un bug, que hace que la conexión tarde un segundo, y tienes mil usuarios simultaneos, lo que antes no afectaba ahora hace que la web no cargue.
      en términos generales, todo lo que sea acceder a información de fuera del código (bases de datos, otras api, sistemas de ficheros, etc), debe ser programado con async/await
      en aplicaciones de esctritorio o moviles la diferencia es minima porque es el usuario el que tiene la app en su dispositivo, asi que a no ser que sea un desastre, el usuario no va a notar la falata de rendimiento, pero en web puede ser un desastre bien gordo.
      Un saludo!

  • @josezavala5972
    @josezavala5972 4 ปีที่แล้ว

    Hola qué tal, entendible vídeo y si que me liado un poco con lo de asincrono por como usarlo ya que si hay mucha info por detrás y me he saturado, lo que me lleva a preguntar en el min 5:17 para usar la conexión a la base usas el openasync con ponerl el Open en asyn ya no es necesario hacerlo con el executereaderasync ?? Y en el min 12:40 aprox dónde usar await variableResultado.result , se puede usar el awaiter().getresult() eh leído algo al respecto que lo diferencia en que result es mas para el lado del compilador y si llegase a arrojar un error lo lanzaría en un grupo de excepciones a usar el awaiter que arrojaría más directo la exception, pero al final fuera del tema de la exception sería indistinto usar cualquiera?

    • @NetMentor
      @NetMentor  4 ปีที่แล้ว +1

      Hola!
      Voy por partes porque la pregutna es bastante larga espero no dejarme nada.
      el motivo por el que uso openAsync es para recibir la conexion de forma asíncrona, esto es para que mientras "esta creando" la conexion, el hilo puede hacer otras cosas.
      Exactamente el mísmo motivo para ExecuteAsync
      puedes hacer conexion.open y luego ExecuteAsync pero si realizas esta accione es probable que cuando haces conexion.open bloquees el hilo, lo que puede causar una perdida de rendimiento.
      Respecto a la segunda parte "variableResultado.result"
      Si es cierto que Task.GetAwaiter().GetResult() es mejor que .wait y .Result principalmente por el motivo que has contado, que propaga la excepción en vez de tener una Aggregate exception.
      Pero este caso en concreto es un poco diferente, ya que para ejecutamos un Task.WhenAll() y es este task.WhenAll el que esta haciendo el await, una de las caracteristicas de la palabra clave await es que te devuelve la excepción que necesitas en vez de aggregateexception.
      Si bien es cierto que nos devuleve solo la primera de las excepciones, es "el precio a pagar", de todas formas las excepciones son eso, excepciones que no deben ocurrir. (podriamos modificar el código para leer ambas, pero por defecto solo es una)
      Y es mejor que cualquier alternativa ya que por ejemplo .GetAwaiter().GetResult() no es realmente asíncrono ya que bloquea el hilo hasta que termina.
      espero que haya quedado claro, un saludo :D

    • @josezavala5972
      @josezavala5972 4 ปีที่แล้ว

      @@NetMentor si ,creo que me suelo crear preguntas algo largas hehehe pero muchas gracias por responder y si, si me aclaraste más mis dudas, si veo que al usar el await ya te da la exception unica y no todo el grupo y por eso se usa result al usar await ..... Si solo mi método retornara nose, un entero y adentro mando a llamar una tarea entoces esa tarea si debo de tratarla de preferencia con awaiter().getresult(), es decir:
      Var resulTask= un método o algo que devuelve un Task;
      Int result = resultTask.awaiter().getresult();
      Return result;
      Con await
      (Cómo en el vídeo)
      Ami Método le pongo
      async Int MiMetodo(){
      Var resulTask= un método o algo que devuelve un Task;
      Int result = await resultTask.result();
      Return result;
      Espero igual haber dado a entender explicando un poco de lo que eh entendido :) sin embargo muchas gracias por tu tiempo

    • @NetMentor
      @NetMentor  4 ปีที่แล้ว +1

      Hola, nono, si haces await no tienes que hacer .result(); Al hacer await automaticamemte te va a devolver el entero.
      Ej: int entero = await GetEntero();

    • @NetMentor
      @NetMentor  4 ปีที่แล้ว +1

      Si no haces await, lonqie tienes es Task y si accedes ahí a .result te va a dar un error. (Si no haces await)
      Por otro lado cuando ejecutas task.whenall(variabletask) estas haciendo un await a cada uno de los elementos que pasas

    • @josezavala5972
      @josezavala5972 4 ปีที่แล้ว

      @@NetMentor yeah , si ya más entendible muchas gracias..... sin embargo si existen diversos escenarios que considerar cuando y como usar una cosa u la otra en el tema de async/await, Task ,task y el otro mundo de los threads :D

  • @Jel.Awesh.M
    @Jel.Awesh.M 3 ปีที่แล้ว

    Básicamente la gran ventaja de Async/Await es cuando necesitamos ejecutar tareas en pararelo, ¿cierto? ¿Y si sólo hubiera una tarea? ¿no habría ninguna ventaja?

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Hola! pues si y no, me explico, si es cierto que es para ejecutar tareas en paralelo, pero ademas el hilo se queda "liberado" para poderse usar en otra parte del código.
      imagina que haces una consutla sql y esa consulta tarda 10 segundos, pues ese hilo puede ser utilizado por otra parte del código u otra request para asi no tenerlo ahí parado por 10 segundos.
      en acso de que solo hubiera una tarea pues depende, si es una app de consola, pues no influye, pero si es una web, puede ser que si (si te llega otra request) aún así personalmente pondría con async/await todo lo que tenga que hacer llamadas a la red (bases de datos, llamadas a otros serivicios, etc).
      un saludo!

    • @Jel.Awesh.M
      @Jel.Awesh.M 3 ปีที่แล้ว

      @@NetMentor , oh ya veo, ¿y ese comportamiento se ejecuta por defecto? Me refiero al hecho de que el "hilo" se ocupe de otra cosa mientras el Task este ejecutándose.

    • @NetMentor
      @NetMentor  3 ปีที่แล้ว

      Si, bueno Thread es un tipo creado por Microsoft que funciona sobre los hilos, básicamente todo el mundo tenía el problema de administrar los hilos etc, y programaron el tipo Thread para que los developers se olvidarán de toda la administración que es una pesadilla.

  • @Ariel_Fernandez
    @Ariel_Fernandez 2 ปีที่แล้ว

    Zoom = 150%, una lastima desde la TV o celular no se puede ver el código, gracias igual.

    • @NetMentor
      @NetMentor  2 ปีที่แล้ว +1

      Lo se, es un problema que tengo en algunos de los vídeos :(