Saltar al contenido

Entendiendo async / await en C#

Agradeceríamos tu apoyo para difundir nuestros artículos acerca de las ciencias de la computación.

Solución:

Te recomiendo que comiences con mi introducción a async/await y seguimiento con la documentación oficial de MSDN sobre TAP.

Como menciono en mi entrada de blog de introducción, hay varios Task miembros que son vestigios de la TPL y no tienen ningún uso en puro async código. new Task y Task.Start debe ser reemplazado con Task.Run (o TaskFactory.StartNew). Similar, Thread.Sleep debe ser reemplazado con Task.Delay.

Por último, le recomiendo que no utilice Task.WaitAll; su aplicación de consola debería simplemente Wait en un solo Task que utiliza Task.WhenAll. Con todos estos cambios, su código se vería así:

class Program

    static void Main(string[] args)
    
        MainAsync().Wait();
    

    public static async Task MainAsync()
    
        Task task1 = Task1();
        Task task2 = Task2();

        await Task.WhenAll(task1, task2);

        Debug.WriteLine("Finished main method");
    

    public static async Task Task1()
    
        await Task.Delay(5000);
        Debug.WriteLine("Finished Task1");
    

    public static async Task Task2()
    
        await Task.Delay(10000);
        Debug.WriteLine("Finished Task2");
    

Comprender la tarea de C#, asíncrono y espera

Tarea C#

La clase de tarea es un contenedor de tareas asincrónicas. Thread.Sleep(1000) puede detener la ejecución de un subproceso durante 1 segundo. Mientras que Task.Delay(1000) no detendrá el trabajo actual. Ver código:

public static void Main(string[] args)
    TaskTest();

private static void TaskTest()
     Task.Delay(5000);
     System.Console.WriteLine("task done");

Cuando se ejecuta, “tarea terminada” aparecerá inmediatamente. Entonces puedo suponer que todos los métodos de Task deben ser asíncronos. Si reemplazo TaskTest () con Task.Run(() =>TaskTest()) la tarea realizada no aparecerá hasta que agregue Console.ReadLine(); después del método Run.

Internamente, la clase Task representa un estado de subproceso en una máquina de estado. Cada estado en la máquina de estado tiene varios estados, como Iniciar, Retrasar, Cancelar y Detener.

asíncrono y espera

Ahora, puede preguntarse si todas las tareas son asincrónicas, ¿cuál es el propósito de Task.Delay? a continuación, retrasemos realmente el hilo en ejecución usando async y await

public static void Main(string[] args)
     TaskTest();
     System.Console.WriteLine("main thread is not blocked");
     Console.ReadLine();

private static async void TaskTest()
     await Task.Delay(5000);
     System.Console.WriteLine("task done");

asíncrono dígale a la persona que llama, soy un método asíncrono, no me espere. await dentro de TaskTest() solicita esperar la tarea asíncrona. Ahora, después de ejecutarse, el programa esperará 5 segundos para mostrar el texto de la tarea realizada.

Cancelar una tarea

Dado que Task es una máquina de estado, debe haber una forma de cancelar la tarea mientras se está ejecutando.

static CancellationTokenSource tokenSource = new CancellationTokenSource();
public static void Main(string[] args)
    TaskTest();
    System.Console.WriteLine("main thread is not blocked");
    var input=Console.ReadLine();
    if(input=="stop")
          tokenSource.Cancel();
          System.Console.WriteLine("task stopped");
     
     Console.ReadLine();

private static async void TaskTest()
     try
          await Task.Delay(5000,tokenSource.Token);
     catch(TaskCanceledException e)
          //cancel task will throw out a exception, just catch it, do nothing.
     
     System.Console.WriteLine("task done");

Ahora, cuando el programa se está ejecutando, puede ingresar “detener” para cancelar la tarea de retraso.

Tus tareas nunca terminan porque nunca comienzan a ejecutarse.

me gustaría Task.Factory.StartNew para crear una tarea y comenzarla.

public static async Task Task1()

  await Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(5)));
  Debug.WriteLine("Finished Task1");


public static async Task Task2()

  await Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(10)));
  Debug.WriteLine("Finished Task2");

Como nota al margen, si realmente solo está tratando de hacer una pausa en un método asíncrono, no hay necesidad de bloquear un hilo completo, solo use Task.Delay

public static async Task Task1()

  await Task.Delay(TimeSpan.FromSeconds(5));
  Debug.WriteLine("Finished Task1");


public static async Task Task2()

  await Task.Delay(TimeSpan.FromSeconds(10));
  Debug.WriteLine("Finished Task2");

Aquí puedes ver las reseñas y valoraciones de los lectores

Nos encantaría que puedieras dar difusión a este tutorial si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *