Tareas (Task)
La programación asíncrona es una técnica que permite que un programa realice varias tareas simultáneamente. En C#, una forma común de implementar la programación asíncrona es utilizando la clase Task
. La clase Task
se encuentra en el espacio de nombres System.Threading.Tasks
.
Aquí hay un ejemplo de cómo se puede utilizar la clase Task
para realizar una tarea asincrónica:
using System;
using System.Threading.Tasks;
public class Example
{
public static async Task Main()
{
Console.WriteLine("Working...");
await Task.Delay(1000);
Console.WriteLine("Work complete.");
}
}
En este ejemplo, el método Main
se declara como async
y devuelve una tarea. El método Delay
de la clase Task
se utiliza para esperar un segundo antes de continuar con la ejecución del programa. El método await
se utiliza para esperar a que se complete la tarea.
Aquí hay otro ejemplo de cómo se puede utilizar la clase Task
para realizar varias tareas asincrónicas:
using System;
using System.Threading.Tasks;
public class Example
{
public static async Task Main()
{
Task task1 = Task.Run(() => DoWork(1));
Task task2 = Task.Run(() => DoWork(2));
Task task3 = Task.Run(() => DoWork(3));
await Task.WhenAll(task1, task2, task3);
Console.WriteLine("All work complete.");
}
public static void DoWork(int id)
{
Console.WriteLine("Working on task {0}...", id);
Task.Delay(1000).Wait();
Console.WriteLine("Task {0} complete.", id);
}
}
En este ejemplo, se utilizan tres tareas para realizar tres trabajos diferentes. El método Task.Run
se utiliza para crear una tarea y ejecutar el método DoWork
. El método WhenAll
se utiliza para esperar a que se completen todas las tareas.
En C#, async y await son características que permiten escribir código asincrónico de manera más clara y concisa. Aquí te explico cómo funcionan con ejemplos:
- Métodos Asincrónicos con async y await:async: Se utiliza para definir un método asincrónico.await: Se utiliza dentro de un método asincrónico para esperar la finalización de una tarea.
csharp
using System; using System.Threading.Tasks;
class Program { static async Task Main() { await DoAsyncWork(); Console.WriteLine(“Main method continues while waiting for async work.”); }
static async Task DoAsyncWork()
{
Console.WriteLine("Async work started.");
await Task.Delay(2000); // Simula una operación asincrónica
Console.WriteLine("Async work completed.");
}
}
En este ejemplo, DoAsyncWork es un método asincrónico que utiliza await Task.Delay(2000) para simular una operación asincrónica que toma 2 segundos. El método Main utiliza await DoAsyncWork() para esperar a que DoAsyncWork se complete antes de imprimir el mensaje “Main method continues while waiting for async work.”
- Task con async y await:
También puedes utilizar async y await con Task para operaciones que devuelven un resultado.
using System; using System.Threading.Tasks;
class Program { static async Task Main() { int result = await GetResultAsync(); Console.WriteLine($”Result: {result}”); }
static async Task<int> GetResultAsync()
{
Console.WriteLine("Async operation started.");
await Task.Delay(2000);
Console.WriteLine("Async operation completed.");
return 42;
}
}
En este caso, GetResultAsync es un método asincrónico que devuelve un Task. Al llamar a await GetResultAsync(), se espera a que la operación asincrónica se complete y se obtiene el resultado.
- Manejo de Excepciones en Métodos Asincrónicos:
Puedes manejar excepciones en métodos asincrónicos de la misma manera que en métodos sincrónicos.
using System; using System.Threading.Tasks;
class Program { static async Task Main() { try { await ThrowExceptionAsync(); } catch (Exception ex) { Console.WriteLine($”Caught exception: {ex.Message}”); } }
static async Task ThrowExceptionAsync()
{
Console.WriteLine("Async operation with exception started.");
await Task.Delay(1000);
throw new Exception("Something went wrong.");
}
}
Aquí, ThrowExceptionAsync lanza una excepción, y la excepción se maneja en el bloque catch del método Main.
- Task.WhenAll y Task.WhenAny:
Puedes esperar múltiples tareas de manera concurrente utilizando Task.WhenAll y Task.WhenAny.
csharp
using System; using System.Threading.Tasks;
class Program { static async Task Main() { Task task1 = DelayAndReturnAsync(2000, 1); Task task2 = DelayAndReturnAsync(1000, 2);
await Task.WhenAll(task1, task2);
Console.WriteLine($"Result from task1: {task1.Result}, Result from task2: {task2.Result}");
Task<int> firstCompletedTask = await Task.WhenAny(task1, task2);
Console.WriteLine($"First completed task result: {firstCompletedTask.Result}");
}
static async Task<int> DelayAndReturnAsync(int delay, int value)
{
await Task.Delay(delay);
return value;
}
}
En este ejemplo, Task.WhenAll espera a que ambas tareas (task1 y task2) se completen, y Task.WhenAny espera a que cualquiera de las dos tareas se complete.
https://learn.microsoft.com/es-es/dotnet/csharp/asynchronous-programming/async-scenarios