Async/Await y Tasks
C# introdujo async/await en 2012, tres años antes que JavaScript. Task<T> es el equivalente de Promise<T>: representa una operación que se completará en el futuro. La palabra async marca un método como asíncrono y await espera que una Task complete sin bloquear el hilo.
El resultado práctico: tu app puede hacer peticiones HTTP, leer archivos o acceder a la base de datos sin congelar la interfaz de usuario o desperdiciar hilos del servidor esperando.
C# tiene capacidades de concurrencia más avanzadas que JavaScript. Task.WhenAll ejecuta múltiples Tasks en paralelo real (no secuencial como await t1; await t2) y espera que todas terminen. CancellationToken permite cancelar operaciones en vuelo: si el usuario abandona la página, puedes cancelar la consulta a la base de datos. IAsyncEnumerable permite streaming asíncrono: procesa elementos uno por uno conforme llegan en lugar de esperar todos juntos.
using System.Net.Http;
// async method devuelve Task o Task<T>
public async Task<string> ObtenerDatosAsync(string url) {
using var cliente = new HttpClient();
try {
var respuesta = await cliente.GetAsync(url);
respuesta.EnsureSuccessStatusCode();
return await respuesta.Content.ReadAsStringAsync();
} catch (HttpRequestException ex) {
Console.WriteLine($"Error HTTP: {ex.Message}");
throw;
}
}
// Paralelismo con Task.WhenAll
public async Task ProcesarParaleloAsync() {
var tarea1 = ObtenerDatosAsync("https://api.ejemplo.com/users");
var tarea2 = ObtenerDatosAsync("https://api.ejemplo.com/posts");
// Se ejecutan EN PARALELO
var resultados = await Task.WhenAll(tarea1, tarea2);
Console.WriteLine(resultados[0]); // Resultado de tarea1
Console.WriteLine(resultados[1]); // Resultado de tarea2
}
// Task.WhenAny - la que termine primero
public async Task<string> ConTimeout(string url, int ms) {
var solicitud = ObtenerDatosAsync(url);
var timeout = Task.Delay(ms);
var ganadora = await Task.WhenAny(solicitud, timeout);
if (ganadora == timeout)
throw new TimeoutException("Tiempo agotado");
return await solicitud;
}
// CancellationToken
public async Task OperacionCancelableAsync(CancellationToken ct) {
for (int i = 0; i < 10; i++) {
ct.ThrowIfCancellationRequested();
await Task.Delay(1000, ct);
Console.WriteLine($"Paso {i + 1}");
}
}
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(5));
await OperacionCancelableAsync(cts.Token);
// IAsyncEnumerable (C# 8+) - streaming
public async IAsyncEnumerable<int> GenerarAsync() {
for (int i = 0; i < 5; i++) {
await Task.Delay(100);
yield return i;
}
}
await foreach (var n in GenerarAsync()) Console.WriteLine(n);
Practica esta lección
Resuelve los ejercicios del curso de C# en la app, gratis y con corrección automática.
Empezar a practicar