es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuál es el beneficio de C# async/await si todavía espera a que se complete la ejecución anterior?

Intenté leer muchos artículos y preguntas en StackOverflow sobre el uso real de async/await, que básicamente son llamadas de método asíncronas, pero de alguna manera todavía no soy capaz de descifrar cómo proporciona paralelismo y comportamiento sin bloqueo. Me he referido a algunos posts como estos:

https://stackoverflow.com/questions/35380162/is-it-ok-to-use-async-await-almost-everywhere

https://news.ycombinator.com/item?id=19010989

https://stackoverflow.com/questions/28841345/benefits-of-using-async-and-await-keywords

Entonces, si escribo un fragmento de código como este:

var user = await GetUserFromDBAsync();
var destination = await GetDestinationFromDBAsync();
var address = await GetAddressFromDBAsync();

Aunque los tres métodos son asíncronos, el código no irá a la segunda línea para obtener destination de la base de datos hasta que obtenga completamente user de la base de datos.

Entonces, ¿dónde está el paralelismo y el comportamiento sin bloqueo de asyn/await aquí? ¿Todavía espera completar la primera operación antes de ejecutar la siguiente línea?

¿O mi comprensión total de asyn es incorrecta?

EDICIÓN

¡Cualquier ejemplo realmente ayudaría!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Async/await permite que se ejecuten operaciones asíncronas sin bloquear el hilo principal. Aunque parezca que el código del ejemplo no se está ejecutando en paralelo, aún así es no bloqueante. Cuando se llama al método GetUserFromDBAsync(), éste devuelve una tarea para recuperar el usuario de la base de datos. La palabra clave await permite que el hilo principal siga ejecutando mientras la tarea se completa en segundo plano. Cuando se completa la tarea, el valor se devuelve a la variable user y se llama al siguiente método, GetDestinationFromDBAsync(). Esto permite un comportamiento no bloqueante ya que el hilo principal puede seguir ejecutando mientras las tareas asíncronas se completan en segundo plano. Esto puede ser especialmente útil en situaciones donde múltiples operaciones asíncronas necesitan ser ejecutadas en un orden específico, como se muestra en el ejemplo proporcionado.

    Para demostrar la paralelismo, considere el siguiente ejemplo:

    var userTask = GetUserFromDBAsync();
    var destinationTask = GetDestinationFromDBAsync();
    var addressTask = GetAddressFromDBAsync();
    
    await Task.WhenAll(userTask, destinationTask, addressTask);
    
    var user = userTask.Result;
    var destination = destinationTask.Result;
    var address = addressTask.Result;
    

    Aquí, los tres métodos asíncronos se ejecutan en paralelo comenzando sus respectivas tareas y almacenándolas en variables. El método Task.WhenAll() permite que las tres tareas se completen antes de continuar con la siguiente línea de código. Esto permite la paralelismo ya que las tres tareas se ejecutan simultáneamente y no bloquean el hilo principal. Una vez que las tres tareas se completan, los valores se asignan a sus variables respectivas.

Comments are closed.