Ejercicio: Supervisión de variables y flujo de ejecución

Completado

La vista RUN AND DEBUG proporciona a los desarrolladores una manera sencilla de supervisar variables y expresiones, observar el flujo de ejecución y administrar puntos de interrupción durante el proceso de depuración.

Examinar las secciones de la vista Ejecutar y depurar

Cada sección de la vista RUN AND DEBUG proporciona funcionalidades únicas. El uso de una combinación de estas secciones durante el proceso de depuración suele resultar útil.

Sección VARIABLES

El estado de la variable de supervisión es un aspecto importante de la depuración de código. Los cambios inesperados en el estado de variable a menudo ayudarán a identificar errores lógicos en el código.

La sección VARIABLES organiza las variables por ámbito. El Locals ámbito muestra las variables en el ámbito actual (el método actual).

Nota:

La sección de sentencias de nivel superior de una aplicación de consola se considera un método propio. Método denominado Main.

Puede desplegar (expandir) los ámbitos mostrados seleccionando la flecha situada a la izquierda del nombre del ámbito. También puede desplegar variables y objetos. En la captura de pantalla siguiente se muestra la matriz numbers que se desarrolla bajo el ámbito Locals.

Captura de pantalla que muestra una variable desarrollada en la sección Variables de la vista Ejecutar y depurar.

También es posible cambiar el valor de una variable en tiempo de ejecución mediante la sección VARIABLES. Puede hacer doble clic en el nombre de la variable y, a continuación, escribir un nuevo valor.

Sección Reloj

¿Qué ocurre si desea realizar un seguimiento de un estado de variable a lo largo del tiempo o de diferentes métodos? Puede ser tedioso buscar la variable cada vez. Aquí es donde la sección WATCH resulta útil.

Puede seleccionar el botón Agregar expresión (aparece como signo más: +) para escribir un nombre de variable o una expresión que se va a inspeccionar. Como alternativa, puede hacer clic con el botón derecho en una variable en la sección VARIABLES y seleccionar Add to watch.

Todas las expresiones dentro de la sección WATCH se actualizarán automáticamente a medida que se ejecuta el código.

Sección CALL STACK

Cada vez que tu código entra en un método desde otro método, se agrega una capa de llamada a la pila de llamadas de la aplicación. Cuando tu aplicación se vuelve compleja y tienes una larga lista de métodos llamados por otros métodos, la pila de llamadas representa la secuencia de llamadas a métodos.

La sección CALL STACK es útil cuando intenta encontrar la ubicación de origen para una excepción o una expresión WATCH. Si la aplicación produce una excepción inesperada, a menudo verá un mensaje en la consola que se parece a lo siguiente:

Exception has occurred: CLR/System.DivideByZeroException
An unhandled exception of type 'System.DivideByZeroException' occurred in Debug1.dll: 'Attempted to divide by zero.'
    at Program.<<Main>$>g__WriteMessage|0_1() in C:\Users\howdc\Desktop\Debug1\Program.cs:line 27
    at Program.<<Main>$>g__Process1|0_0() in C:\Users\howdc\Desktop\Debug1\Program.cs:line 16
    at Program.<Main>$(String[] args) in C:\Users\howdc\Desktop\Debug1\Program.cs:line 10

El grupo de at Program ... líneas con sangría bajo el mensaje de error se denomina seguimiento de pila. El seguimiento de la pila lista el nombre y origen de cada método llamado previo a la excepción. Sin embargo, la información puede ser un poco difícil de descifrar, ya que también puede incluir información del entorno de ejecución de .NET. En este ejemplo, el seguimiento de la pila es bastante limpio y puede ver que se produjo la excepción en un método denominado WriteMessage. La pila se origina en un método denominado Main, que es la sección de declaraciones de nivel superior de la aplicación de consola.

La sección CALL STACK puede ayudarle a evitar la dificultad de descifrar un seguimiento de pila que está desordenado con la información del entorno de ejecución de .NET. Filtra la información no deseada para mostrar solo los métodos pertinentes de su propio código de forma predeterminada. Puede desenredar manualmente la pila de llamadas para averiguar dónde se originó la excepción.

Sección PUNTOS DE INTERRUPCIÓN

La sección PUNTOS DE INTERRUPCIÓN muestra la configuración actual del punto de interrupción y se puede usar para habilitar o deshabilitar puntos de interrupción específicos durante una sesión de depuración.

Configura tu aplicación y la configuración de inicio

Cuando trabaje en una aplicación de consola que lea la entrada del usuario, probablemente tendrá que actualizar el archivo de configuración de inicio.

  1. Actualice el código en el archivo de Program.cs de la siguiente manera:

    string? readResult;
    int startIndex = 0;
    bool goodEntry = false;
    
    int[] numbers = { 1, 2, 3, 4, 5 };
    
    // Display the array to the console.
    Console.Clear();
    Console.Write("\n\rThe 'numbers' array contains: { ");
    foreach (int number in numbers)
    {
        Console.Write($"{number} ");
    }
    
    // To calculate a sum of array elements, 
    //  prompt the user for the starting element number.
    Console.WriteLine($"}}\n\r\n\rTo sum values 'n' through 5, enter a value for 'n':");
    while (goodEntry == false)
    {
        readResult = Console.ReadLine();
        goodEntry = int.TryParse(readResult, out startIndex);
    
        if (startIndex > 5)
        {
            goodEntry = false;
            Console.WriteLine("\n\rEnter an integer value between 1 and 5");
        }
    }
    
    // Display the sum and then pause.
    Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex)}");
    
    Console.WriteLine("press Enter to exit");
    readResult = Console.ReadLine();
    
    // This method returns the sum of elements n through 5
    static int SumValues(int[] numbers, int n)
    {
        int sum = 0;
        for (int i = n; i < numbers.Length; i++)
        {
            sum += numbers[i];
        }
        return sum;
    }
    
  2. Tómese un minuto para revisar el código.

    Tenga en cuenta lo siguiente:

    • El código especifica una matriz de enteros que contiene cinco números.
    • El código muestra la salida en la consola.
    • El código solicita al usuario que escriba un número como número del elemento inicialn, que usa para sumar los elementos de la matrizn hasta5.
    • El código calcula la suma en un método, muestra los resultados en la consola y, a continuación, se pausa.

    Nota:

    El panel CONSOLA DE DEPURACIÓN no admite la entrada de usuario desde la consola.

  3. En el menú Archivo de Visual Studio Code, seleccione Guardar.

  4. En el menú Ejecutar , seleccione Quitar todos los puntos de interrupción.

    Esto quita los puntos de interrupción que quedan del ejercicio anterior.

  5. En la vista EJECUTAR Y DEPURAR, seleccione Iniciar depuración.

  6. Observe que se produce un error cuando se ejecuta la línea de Console.Clear(); código.

  7. En la barra de herramientas Depurar, seleccione Detener.

  8. Cambie a la vista EXPLORER y abra el archivo launch.json en el Editor.

  9. Actualice el valor del atributo de la siguiente manera:

    "console":"integratedTerminal",
    
  10. En el menú Archivo de Visual Studio Code, seleccione Guardar y, a continuación, cierre el archivo launch.json.

Revisión de la salida de la aplicación e identificación de problemas

Revisar la salida de la aplicación puede revelar problemas lógicos que ha pasado por alto al escribir el código.

  1. Vuelva a la vista EJECUTAR Y DEPURAR.

  2. En la vista EJECUTAR Y DEPURAR, seleccione Iniciar depuración.

    Los mensajes que se muestran en el panel CONSOLA DE DEPURACIÓN muestran el depurador que se asocia a la aplicaciónDebug101.dll.

  3. Observe que no se muestran mensajes de error.

    El cambio del valor del console atributo de internalConsole a integratedTerminal en el archivo de configuración de inicio ha corregido el error de la consola. Pero ahora debe buscar la consola que contiene el resultado.

  4. En el área Paneles debajo del Editor, cambie del panel CONSOLA DE DEPURACIÓN al panel TERMINAL.

  5. Observe que la ejecución del código se ha pausado en el mensaje que pide al usuario que escriba un valor para n.

    La salida del panel TERMINAL debe ser similar a la siguiente:

    
    The 'numbers' array contains: { 1 2 3 4 5 }
    
    To sum values 'n' through 5, enter a value for 'n':
    
  6. En el símbolo del sistema de TERMINAL, escriba 3.

  7. Revise la salida de la aplicación.

    La salida del panel TERMINAL debe ser similar a la siguiente:

    
    The 'numbers' array contains: { 1 2 3 4 5 }
    
    To sum values 'n' through 5, enter a value for 'n':
    3
    
    The sum of numbers 3 through 5 is: 9
    press Enter to exit
    
  8. Dedique un minuto a tener en cuenta el valor notificado de sum y los valores de los elementos de matriz de 3 a 5 que se muestran en la parte superior de la consola.

    El mensaje dice: The sum of numbers 3 through 5 is: 9. Sin embargo, los elementos de matriz de 3 a 5 son 3, 4y 5. ¿No debería ser 12 la suma notificada?

    Puede usar la sección VARIABLES de la vista RUN AND DEBUG para investigar el problema.

Supervisión del estado de la variable

En algunos casos, simplemente supervisar el estado de la variable es suficiente para identificar el problema de lógica en la aplicación.

  1. Establezca un punto de interrupción en la siguiente línea de código:

    Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex)}");
    
  2. En la vista EJECUTAR Y DEPURAR, seleccione Iniciar depuración.

  3. Cambie del panel CONSOLA DE DEPURACIÓN al panel TERMINAL.

  4. En el símbolo del sistema de TERMINAL, escriba 3.

    La ejecución del código se pausará en el punto de interrupción.

  5. Dedique un minuto a revisar la sección VARIABLES de la vista EJECUTAR Y DEPURAR.

    Observe que startIndex se le ha asignado el valor especificado, que es 3.

  6. Seleccione Paso a paso por instrucciones.

  7. Observe que se actualizan las secciones VARIABLES y PILA DE LLAMADAS.

    En la sección PILA DE LLAMADAS se muestra que la ejecución de código se ha movido al método SumValues.

    La sección VARIABLES, que enumera las variables locales, muestra el valor del entero n. Al parámetro n de método se le asigna su valor del argumento startIndexde llamada al método . En este caso, el cambio a los nombres de variable hace que se borre el valor que se ha pasado, no un puntero de referencia.

    Nota:

    En este caso, verá la mayoría del código en el Editor, por lo que es posible que no necesite la sección PILA DE LLAMADAS. Sin embargo, cuando esté trabajando en aplicaciones más grandes con llamadas de método profundamente anidadas e interconectadas, la ruta de ejecución mostrada en la sección PILA DE LLAMADAS puede ser extremadamente útil.

  8. Continúe seleccionando Entrar paso a paso hasta que el valor asignado a sum ya no sea 0.

  9. Dedique un minuto a revisar la información que se muestra en la sección VARIABLES.

    Verá lo siguiente:

    Captura de pantalla que muestra la sección Variables de la vista Ejecutar y depurar.

    Observe que el valor asignado a sum pasó de 0 a 4.

  10. Para expandir la numbers matriz, seleccione números [int[]]..

    Captura de pantalla que muestra los elementos de matriz expandidos en la sección Variables de la vista Ejecutar y depurar.

  11. Recuerde que se accede a los elementos de matriz mediante números de índice de base cero.

    En este caso, el error lógico es una discrepancia entre las instrucciones de la interfaz de usuario y el código subyacente. La interfaz de usuario hace referencia a los elementos de matriz 1 a 5. Sin embargo, el código usa el valor especificado por el usuario para tener acceso a los elementos de matriz de base cero. El elemento de matriz que tiene un índice de 3 almacena un valor de 4. El código no compensa los números de índice de base cero.

  12. Para finalizar la sesión de depuración, seleccione Detener.

  13. Dedique un minuto a tener en cuenta cómo podría corregir el problema.

    Este problema se puede corregir en la interfaz de usuario; para ello, pida al usuario que escriba un valor entre 0 y 4. También se puede corregir en el código restando 1 del valor especificado. Por lo general, tu objetivo debe ser que la interfaz de usuario sea clara y fácil de seguir. En este caso, podría ser mejor actualizar el código de la siguiente manera:

    Console.WriteLine($"\n\rThe sum of numbers {startIndex} through {numbers.Length} is: {SumValues(numbers, startIndex - 1)}");
    

    Al ejecutar el código actualizado, se producirá la siguiente salida:

    Captura de pantalla que muestra la salida después de actualizar la lógica de la aplicación.

  14. Actualice el código mediante el enfoque sugerido y guarde el archivo Program.cs.

  15. Borre el punto de interrupción, vuelva a ejecutar la aplicación en el depurador y compruebe que el resultado previsto se muestra en el panel TERMINAL.

    Has utilizado el estado de la variable para identificar y corregir un problema lógico. Buen trabajo.

Supervisión de expresiones de inspección

La sección WATCH se puede usar para supervisar expresiones basadas en una o varias variables.

Supongamos que está trabajando en una aplicación que realiza cálculos numéricos en un conjunto de datos. Cree que el código genera resultados no confiables cuando la relación entre dos variables numéricas es mayor que 5. Puede usar la sección WATCH para supervisar la relación calculada.

  1. Actualice el archivo Program.cs con el código siguiente:

    bool exit = false;
    var rand = new Random();
    int num1 = 5;
    int num2 = 5;
    
    do
    {
        num1 = rand.Next(1, 11);
        num2 = num1 + rand.Next(1, 51);
    
    } while (exit == false);
    
  2. Guarde el archivo Program.cs.

  3. Establezca un punto de interrupción en la línea de código final.

  4. Establezca la siguiente expresión WATCH:

    num2 / num1 > 5
    
  5. En la vista EJECUTAR Y DEPURAR, seleccione Iniciar depuración.

  6. Observe los valores mostrados en las secciones VARIABLES y WATCH.

  7. Seleccione Continuar hasta que vea que la expresión WATCH se evalúa como true.

    Si la expresión WATCH se evalúa como true en la primera iteración, seleccione Continuar varias veces o hasta que vea true una segunda vez.

  8. Dedique un minuto a tener en cuenta cómo se usa la sección WATCH.

    En este escenario, ha determinado que el código genera resultados no confiables cuando la relación entre dos variables numéricas es mayor que 5. Ha creado una expresión en la sección WATCH que representa esta condición. Ahora puede usar la sección WATCH para realizar un seguimiento de esa condición.

Modificar el valor asignado a una variable en la sección VARIABLES

Puede haber ocasiones en las que quiera crear manualmente una condición de programación. La sección VARIABLES de la vista RUN AND DEBUG le permite hacerlo cambiando el estado de una variable en tiempo de ejecución.

  1. Dedique un minuto a revisar el código que está ejecutando.

    Observe que el código nunca se cerrará del do bucle porque exit nunca será true. Esta no es una condición mediante programación que necesita modificar en una aplicación real, pero demuestra la funcionalidad.

  2. En la sección VARIABLES, haga clic con el botón derecho en exit [bool]y, a continuación, seleccione Establecer valor.

    La sección VARIABLES permite cambiar el valor asignado a una variable en tiempo de ejecución. Esto puede ser útil cuando desea ver cómo reacciona el código a una condición determinada.

  3. Para establecer el valor de exit en true, escriba true y presione Entrar.

    En este caso, cambiar el valor de exit a true hará que la aplicación se cierre cuando se ejecute la while instrucción .

  4. Selecciona Continuar.

  5. Observe que el panel DEBUG CONSOLE muestra un mensaje que le informa de que el programa ha salido.

¡Felicidades! Ha usado correctamente las secciones VARIABLES y WATCH de la vista RUN AND DEBUG.

Resumen

Estos son algunos de los aspectos más importantes que debe recordar de esta unidad:

  • Supervise el estado de las variables mediante la sección VARIABLES de la vista RUN AND DEBUG.
  • Realice un seguimiento de una expresión a lo largo del tiempo o de diferentes métodos mediante la sección WATCH de la vista RUN AND DEBUG.
  • Use la sección CALL STACK de la vista EJECUTAR Y DEPURAR para buscar la ubicación de origen de una excepción o una expresión WATCH.
  • Use la sección VARIABLES para cambiar el valor asignado de una variable en tiempo de ejecución.