👽
3ntr0 Apuntes
  • 📚Principios SOLID y Clean Code
    • 💲Deuda Técnica
    • 📌Mejorar Nombres
      • 📄Nombre según Tipo
      • 🚗Nombre Clases
      • ⚙️Nombres Funciones
    • ☑️Mejorar Funciones
    • ➿Principio DRY
    • 🧼Clean Code en Clases (POO)
      • 📘 Principio de Responsabilidad Única (SRP)
    • 🤮🇸 🇹 🇺 🇵 🇮 🇩 - Code Smells
      • 🚫Singleton
      • 🙏Tight Coupling
      • 🥸U P I D
      • 🚩Más Code Smells
  • 💕Angular
    • 🏍️Standalone
    • 🆚ngClass vs [class.clase]
    • 🩻Directivas
    • 🚩ElementRef
    • 🎀Decoradores
      • @HostListener
    • 🔄OnChanges
    • 🧪Testing - Jasmine y Karma
      • 🚀Módulo 1: Introducción a las pruebas unitarias
      • 🧫Módulo 2: Introducción a Jasmine
      • ⚒️Módulo 3: Introducción a Karma
      • 🔬Módulo 4: Pruebas unitarias en Angular
        • Código comentado Paso a Paso
      • 🕵️‍♂️Módulo 5: Técnicas avanzadas en Jasmine
      • 📚Módulo 6: Técnicas avanzadas en Karma
  • 🖼️HTML y CSS
    • 🖌️Custom Properties
    • Trucos
    • Brakepoints
  • 🧋Javascript
    • 🛠️Funciones
    • 📦Arrays
      • Every y Some
      • Map
      • Reduce
    • 😎Hoisting
    • 🪚Desestructuración
    • 🛻Programación Asincrona
      • 📞Callbacks
      • 🌟Promises
      • 🆚Promise.all Y Promise.any
      • 🚀Async/Await
    • Respuestas HTTP
    • 🧐Dudas Básicas
      • NodeList
      • 🧐Contextos de .this
      • 💭Parametro Rest
      • 🗨️arguments
      • 🙀JavaScript no tiene clases
      • 🆚Null vs Undefined
      • 🔎Operador in
      • 🟨Operador Spread
      • ❓Encadenamiento Opcional
      • 🔲Notación de Corchetes
      • ⛓️Coalescencia Nula (??)
      • 🆚Shallow Copy vs Deep Copy
      • 🆚.json VS JSON.parse
      • ⚙️Fetch wrapper
      • Sets
      • Maps
  • 📒Terminología
    • 💎Esenciales
    • Web
    • Javascript
  • 🌐GIT
    • Source Tree
  • 🧬React
    • 🫂Babel
  • 🔧 Fundamentos de C#
    • 🎛️General
      • 🧐Diferencia Equals y ==
      • 🧐Diferencia entre typeof y .GetType()
      • 📐Convenciones de Nomenclatura
    • 💠Summary
    • 📇.resx
    • 📄Strings
      • ⛓️Comparación de cadenas
    • 🧲Regex
    • 📦POO
      • 🚙Clases
        • ✏️Clase String
        • 📥Métodos de Acceso
        • ⚗️Métodos de Extensión
    • 🖇️Pattern Matching
    • 🚩Excepciones
    • Programación Asíncrona
    • 🔎LINQ
      • 🅿️PLINQ
  • 🌐 Desarrollo Web con ASP.NET
    • 🧬Modelos
      • 🗒️Data Annotations
        • 📑Lista
        • 🧪Atributos
          • 🛠️Atributos Personalizados
          • 🧰AttributeUsage
          • 📥Acceso a los atributos
        • 📚Documentación
    • 👷Servicios
      • ⭐Servicios Singleton
    • ⏳Sesiones
      • 🧭Temp Data
    • DbContext
      • 🔄Eager Loading
    • 🥽Manejo de Datos
      • 🗃️Archivos
        • 📤Subida de Archivos
        • ✏️Leer y Escribir
        • 🕓Manejo de Archivos Temporales
        • 🛡️Validación de Archivos en ASP.NET Core
      • Colecciones
        • 🪜Pila (Stack)
        • 🏇Cola (Queue)
      • 🩻Manejo de XMLs
        • 📂XmlDocument
          • 🎯XPath
        • 🧿XmlReader
    • ❤️Tips y Utilities
      • 🟰StringComparison
    • 🧰Debug Tools
      • 🧭Stopwatch
  • 🚀Razor
    • 🧱Configuración de Proyecto
    • 📃Pages
      • 🔸Método OnGet
      • 🔸Carpeta Models
      • 🔸Partial Pages
    • 🎨Layouts
      • Aplicar CSS A UNA PAGE
    • 🚴‍♂️Routing
    • 🏢_ViewImports
    • ✒️Sintaxis Razor
      • 😀Introducción
      • 📔Expresiones Implícitas
      • 📕Expresiones Explícitas
      • ✍️Renderizar Texto
      • 🧑‍🔬Class Page Model
      • 🔖Tag Helpers
        • 🔹asp-page
        • 🔹asp-append-version
        • 🔹asp-for
        • 🔹asp-items
        • 🔹asp-action y asp-controller
  • 🔮LUA
    • 🎯Fundamentos
    • ⌨️Entrada por Consola
    • 🔗Estructuras de Control
    • ⚒️Funciones
    • 📦Tablas
    • 📚Funciones y Librerías Estándar
    • 🦖POO
Con tecnología de GitBook
En esta página
  1. 🔧 Fundamentos de C#

Programación Asíncrona

AnteriorExcepcionesSiguienteLINQ

Última actualización hace 1 año

Asincronía:

🌀 Definición: Ejecución de tareas de forma que no se bloqueen entre sí, permitiendo que el hilo principal continúe ejecutando otras operaciones.

🔄 Importancia: Permite mejorar el rendimiento y la capacidad de respuesta de las aplicaciones, especialmente en operaciones que dependen de recursos externos como I/O o solicitudes de red.

Task en Programación:

📦 Definición: Representa una operación asíncrona en curso. No es el resultado final, sino un marcador de progreso. (Sustituimos void por Task , y si el método devuelve algo sera Task<Algo>)

🛠 Uso: Permite consultar el estado de la operación (en curso, completada, etc.) y obtener el resultado una vez completada.

Palabras Clave: Async y Await:

🚦 Async: Indica que una función puede contener operaciones asíncronas. Permite que la función retorne una Task.

⏸ Await: Se utiliza para esperar el resultado de una operación asíncrona sin bloquear el hilo de ejecución.

🔹 Ejemplos Prácticos: Preparar un Desayuno

  • Ejecución Síncrona:

    • ✅ Descripción: Se realiza una tarea tras otra. Cada tarea debe completarse antes de iniciar la siguiente.

    • 🍳 Ejemplo: Primero hervir agua para el café, luego freír los huevos, después cocinar el bacon, y finalmente tostar el pan.

  • Ejecución Paralela:

    • ✅ Descripción: Varias tareas se ejecutan al mismo tiempo en diferentes hilos o procesadores.

    • 🍳 Ejemplo: Mientras se hierve el agua en un hilo, simultáneamente en otro hilo se fríen los huevos.

  • Ejecución Asíncrona:

    • ✅ Descripción: Se inicia una tarea y mientras esta se completa, se pueden realizar otras tareas.

    • 🍳 Ejemplo: Poner a hervir agua y mientras se calienta, empezar a freír los huevos. No es necesario esperar a que el agua hierva para comenzar con los huevos.

En código se vería algo así : Sincrono :

class Program
{
    static void Main(string[] args)
    {
        Coffee cup = PourCoffee();
        Console.WriteLine("coffee is ready");

        Egg eggs = FryEggs(2);
        Console.WriteLine("eggs are ready");

        Bacon bacon = FryBacon(3);
        Console.WriteLine("bacon is ready");

        Toast toast = ToastBread(2);
        ApplyButter(toast);
        ApplyJam(toast);
        Console.WriteLine("toast is ready");

        Juice oj = PourOJ();
        Console.WriteLine("oj is ready");
        Console.WriteLine("Breakfast is ready!");
    }

    private static Juice PourOJ()
    {
        Console.WriteLine("Pouring orange juice");
        return new Juice();
    }

    private static void ApplyJam(Toast toast) =>
        Console.WriteLine("Putting jam on the toast");

    private static void ApplyButter(Toast toast) =>
        Console.WriteLine("Putting butter on the toast");

    private static Toast ToastBread(int slices)
    {
        for (int slice = 0; slice < slices; slice++)
        {
            Console.WriteLine("Putting a slice of bread in the toaster");
        }
        Console.WriteLine("Start toasting...");
        Task.Delay(3000).Wait();
        Console.WriteLine("Remove toast from toaster");

        return new Toast();
    }

    private static Bacon FryBacon(int slices)
    {
        Console.WriteLine($"putting {slices} slices of bacon in the pan");
        Console.WriteLine("cooking first side of bacon...");
        Task.Delay(3000).Wait();
        for (int slice = 0; slice < slices; slice++)
        {
            Console.WriteLine("flipping a slice of bacon");
        }
        Console.WriteLine("cooking the second side of bacon...");
        Task.Delay(3000).Wait();
        Console.WriteLine("Put bacon on plate");

        return new Bacon();
    }

    private static Egg FryEggs(int howMany)
    {
        Console.WriteLine("Warming the egg pan...");
        Task.Delay(3000).Wait();
        Console.WriteLine($"cracking {howMany} eggs");
        Console.WriteLine("cooking the eggs ...");
        Task.Delay(3000).Wait();
        Console.WriteLine("Put eggs on plate");

        return new Egg();
    }

    private static Coffee PourCoffee()
    {
        Console.WriteLine("Pouring coffee");
        return new Coffee();
    }
}

Asincrono :

public static async Task Main(string[] args)
    {
        Coffee cup = PourCoffee();
        Console.WriteLine("coffee is ready");

        Task<Toast> toastTask = ToastBreadAsync(2);
        Task<Egg> eggsTask = FryEggsAsync(2);
        Task<Bacon> baconTask = FryBaconAsync(3);
        Juice oj = PourOJ();
        Console.WriteLine("oj is ready");

        Toast toast = await toastTask;
        ApplyButter(toast);
        ApplyJam(toast);

        Egg eggs = await eggsTask;
        Bacon bacon = await baconTask;

        Console.WriteLine("Breakfast is ready!");
    }

    private static Juice PourOJ()
    {
        Console.WriteLine("Pouring orange juice");
        return new Juice();
    }

    private static void ApplyJam(Toast toast) =>
        Console.WriteLine("Putting jam on the toast");

    private static void ApplyButter(Toast toast) =>
        Console.WriteLine("Putting butter on the toast");

    private static async Task<Toast> ToastBreadAsync(int slices)
    {
        for (int slice = 0; slice < slices; slice++)
        {
            Console.WriteLine("Putting a slice of bread in the toaster");
        }
        Console.WriteLine("Start toasting...");
        await Task.Delay(3000);
        Console.WriteLine("Remove toast from toaster");

        return new Toast();
    }

    private static async Task<Bacon> FryBaconAsync(int slices)
    {
        Console.WriteLine($"putting {slices} slices of bacon in the pan");
        Console.WriteLine("cooking first side of bacon...");
        await Task.Delay(3000);
        for (int slice = 0; slice < slices; slice++)
        {
            Console.WriteLine("flipping a slice of bacon");
        }
        Console.WriteLine("cooking the second side of bacon...");
        await Task.Delay(3000);
        Console.WriteLine("Put bacon on plate");

        return new Bacon();
    }

    private static async Task<Egg> FryEggsAsync(int howMany)
    {
        Console.WriteLine("Warming the egg pan...");
        await Task.Delay(3000);
        Console.WriteLine($"cracking {howMany} eggs");
        Console.WriteLine("cooking the eggs ...");
        await Task.Delay(3000);
        Console.WriteLine("Put eggs on plate");

        return new Egg();
    }

    private static Coffee PourCoffee()
    {
        Console.WriteLine("Pouring coffee");
        return new Coffee();
    }
}

Consejos:

  1. Operaciones de E/S (Entrada/Salida): Siempre que tu función realice operaciones de E/S, como leer o escribir en un archivo, hacer solicitudes de red, interactuar con bases de datos o llamar a servicios web, deberías considerar hacerla asincrónica. Estas operaciones pueden tardar un tiempo significativo y bloquearían el hilo principal si se ejecutan de manera síncrona.

  2. Operaciones de larga duración: Si tu función realiza un trabajo que consume mucho tiempo (por ejemplo, procesamiento de imágenes, cálculos intensivos), y no quieres que tu aplicación se quede "congelada" o no responda durante este tiempo, deberías hacer esa función asincrónica.

  3. Interfaz de usuario fluida: En aplicaciones de escritorio, móviles o web, si una operación puede afectar la fluidez o la capacidad de respuesta de la interfaz de usuario, debería ejecutarse de manera asincrónica. Por ejemplo, cargar datos al iniciar una aplicación o realizar una consulta de búsqueda en una base de datos.

  4. Escalabilidad: En aplicaciones del lado del servidor, como las APIs web, usar asincronía ayuda a manejar un gran número de solicitudes concurrentes de manera más eficiente, ya que libera hilos para atender nuevas solicitudes mientras espera que las operaciones de E/S se completen.

  5. No para todo: No todas las funciones deben ser asincrónicas. Si una función realiza cálculos rápidos en memoria o tareas que se completan casi instantáneamente, no hay beneficio en hacerlas asincrónicas y puede incluso introducir una sobrecarga innecesaria.

  6. Cadenas de asincronía: Si una función llama a otra que es asincrónica, generalmente esa función también debería ser asincrónica. Esto evita que se bloqueen los hilos y ayuda a mantener la asincronía a lo largo de toda la cadena de llamadas.