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.

¿Por qué mi código asíncrono se ejecuta en otro hilo?

He estado aprendiendo programación asíncrona con async/await y cómo se involucra el enhebrado. Me he dado cuenta de que es una excelente forma de lograr concurrencia sin bloquear el hilo principal con una tarea de E/S. También he leído que las tareas de E/S no están limitadas por la CPU y, por lo tanto, no requieren un hilo. Con eso en mente, el siguiente programa me confunde:

static async Task Main()
{
    //Recuperar el ID del hilo
    Console.WriteLine($"ID del hilo principal: {Thread.CurrentThread.ManagedThreadId}");

    //Trabajo asíncrono/tarea de E/S: obtener google.com
    Task<string> goToGoogle = GetGoogle();

    //Hacer trabajo (basado en la CPU)
    Console.WriteLine("Realizando cálculos...");
    Thread.Sleep(2000);
    Console.WriteLine("Cálculos completos");

    //Almacenar página web para uso posterior
    string page = await goToGoogle;
}

static async Task<string> GetGoogle()
{
   var client = new HttpClient();
   Console.WriteLine($"ID del hilo GetGoogle antes de la solicitud: {Thread.CurrentThread.ManagedThreadId}");
   var page = await client.GetStringAsync("http://google.com");
   Console.WriteLine($"ID del hilo GetGoogle después de la solicitud: {Thread.CurrentThread.ManagedThreadId}");
   return page;
}

//SALIDA
//ID del hilo principal: 1
//ID del hilo GetGoogle antes de la solicitud: 1
//Realizando cálculos...
//ID del hilo GetGoogle después de la solicitud: 7
//Cálculos completos

Como se muestra, el método asíncrono (GetGoogle) se ejecuta en otro hilo. A partir de la ubicación de los registros de ID de hilo en GetGoogle, se utiliza un nuevo hilo tan pronto como se realiza la solicitud. No me queda claro por qué se ha creado otro hilo para ejecutar la tarea supuestamente limitada por E/S, que aparentemente no debería requerir un hilo según lo que he leído.

Entonces, ¿por qué se utiliza un nuevo hilo para realizar esta tarea de E/S? Realmente apreciaría alguna aclaración sobre este concepto.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Si bien es cierto que las tareas de E/S no están limitadas por la CPU y no requieren un hilo, es importante tener en cuenta que en el caso de async/await, la tarea no es completamente limitada por la E/S.

    Cuando se utiliza la palabra clave async/await, se le indica al compilador que cree una máquina de estados y divida el método en partes. La primera parte del método se ejecuta de forma sincrónica hasta que encuentra la palabra clave await, momento en el que el método se divide. En ese punto, la parte del método relacionada con la E/S (en este caso, la llamada a GetStringAsync()) es esperada, y el control se devuelve al método llamador.

    Cuando el control se devuelve al método llamador, este puede continuar ejecutándose en el mismo hilo hasta que se complete la tarea esperada. Una vez que la tarea de E/S se completa, la máquina de estados reanuda la ejecución del método original. Sin embargo, debido a que el hilo original puede haber sido liberado y estar ejecutando otro código en este punto, la ejecución reanudada del método puede no estar en el mismo hilo en el que comenzó.

    Entonces, en resumen, la tarea de E/S en sí misma puede no requerir un hilo, pero la máquina de estados creada por async/await sí requiere un hilo para realizar el cambio de contexto necesario y continuar con el método original. Por eso se utiliza un nuevo hilo para realizar la tarea de E/S.

Comments are closed.