Dado este:
private static async Task<int> Operation1() { await Task.Delay(1000); return 1; } private static async Task<int> Operation2() { await Task.Delay(1000); return 1; } esto se ejecuta secuencialmente, es decir, tarda 2 segundos (medido con Stopwatch )
var a = await Operation1(); var b = await Operation2(); var result = Operation3(a, b);mientras que esto toma solo 1 segundo, ejecutando las cosas en paralelo:
var taskA = Operation1(); var taskB = Operation2(); var a = await taskA; var b = await taskB; var result = Operation3(a, b);¿Porqué es eso? Asumiría totalmente que esos 2 son equivalentes y producen el mismo IL.
En el primer caso Operation2() no se ejecuta ni inicia una tarea hasta que se completa la tarea devuelta por Operation1() .
En el segundo caso, tanto Operation1() como Operation2() se ejecutan, creando e iniciando sus tareas antes de await la finalización de la tarea devuelta por Operation1()
En el primer ejemplo, inicia Operation1 y espera hasta que finalice, luego inicia Operation2 .
En el segundo ejemplo, inicia Operation1 y luego Operation2 , después de lo cual espera Operation1 y luego Operation2 .
Entonces Operation1 y Operation2 se ejecutan en paralelo en el segundo ejemplo y secuencialmente en el primero.
El primer fragmento de código es equivalente a esto:
var taskA = Operation1(); var a = await taskA; // At this point the taskA is completed var taskB = Operation2(); var b = await taskB;Ahora debería ser obvio por qué no es equivalente a la segunda versión:
var taskA = Operation1(); var taskB = Operation2(); // At this point both tasks are started, and probably none is completed var a = await taskA; var b = await taskB;Como nota al margen, uno de estos dos enfoques demuestra una mala práctica. ¿Puedes adivinar si es el primer o el segundo enfoque? Puede encontrar la respuesta a este cuestionario en la primera revisión de esta respuesta.