Marzo de 2016

Volumen 31, número 3

Visual Studio: mejoras en la depuración de Visual Studio 2015

Por Andrew Hall | Marzo de 2016

Aunque nos esforzamos al máximo para escribir código que funcione correctamente a la primera, la realidad es que, como desarrolladores, empleamos una gran cantidad de tiempo depurando. Visual Studio 2015 introdujo nuevas funcionalidades y mejoras para ayudar a los desarrolladores a identificar los problemas en etapas tempranas del ciclo de desarrollo, así como para mejorar la capacidad de encontrar y corregir errores. En este artículo, revisaré las mejoras que se agregaron a Visual Studio 2015 para los desarrolladores de .NET y de C++.

Comenzaré analizando dos mejoras de facilidad de uso y la adición de herramientas de rendimiento que funcionan durante la depuración para Microsoft .NET Framework y C++. Después, profundizaré en un conjunto de mejoras específicas para el desarrollo de .NET y finalizaré con nuevos desarrollos para desarrolladores de C++.

Configuración de puntos de interrupción

Los puntos de interrupción son una funcionalidad del depurador y es muy probable que las utilizara la última vez que trabajó con el depurador. Hay ocasiones en las que el uso de puntos de interrupción condicionales puede ayudar a encontrar el origen de un error mucho más rápido. En Visual Studio 2015, es más sencillo aprovechar los puntos de interrupción condicionales gracias a la introducción de una ventana de configuración de punto de interrupción no modal que se sitúa en contexto con el código. También permite que se combinen fácilmente distintas configuraciones dentro de la misma ventana.

Para la revisión, Visual Studio 2015 ofrece las características siguientes para los puntos de interrupción:

  • Las expresiones condicionales solo interrumpen la ejecución cuando se cumplen las condiciones especificadas. Es el equivalente lógico de agregar una instrucción if al código y colocar el punto de interrupción dentro de ella, de forma que solo se alcance cuando las condiciones sean verdaderas. Las expresiones condicionales son útiles cuando dispone de código al que se llama en varias ocasiones, pero el error solo se produce con una entrada concreta, por lo que resultaría tedioso tener que comprobar manualmente los valores y luego continuar con la depuración.
  • El número de llamadas solo interrumpe la ejecución cuando el punto de interrupción se ha alcanzado un número determinado de veces. Resultan de utilidad en situaciones en las que se llama al código varias veces y se conoce exactamente cuando se produce el error o se tiene una idea general de que "se produce después de como mínimo" un número determinado de iteraciones.
  • Los filtros interrumpen la ejecución cuando se alcanza el punto de interrupción en un subproceso, un proceso o una máquina concretos. Los puntos de interrupción de filtro son útiles para la depuración de código que se ejecute en paralelo cuando solo quiere detener una única instancia.
  • El registro de un mensaje (denominado punto de seguimiento) imprime un mensaje en la ventana de salida y es capaz de reanudar automáticamente la ejecución. Los puntos de seguimiento son útiles para realizar registros temporales cuando es necesario hacer un seguimiento de algo y no quiere tener que interrumpir la ejecución y realizar un seguimiento manualmente de cada valor.

Para ilustrar el valor de los puntos de interrupción condicionales, observe el ejemplo que se muestra en la Figura 1, en el que las aplicaciones se recuperan por tipo dentro de un bucle. El código funciona para la mayoría de cadenas de entrada y solo produce un error cuando la entrada es "desktop". Una opción es establecer un punto de interrupción y luego inspeccionar el valor de appType cada vez que se alcance hasta que sea "desktop", de forma que se pueda comenzar a recorrer paso a paso la aplicación para ver qué es lo que no funciona. Sin embargo, será mucho más rápido crear un punto de interrupción con una expresión condicional que solo interrumpa la ejecución cuando el valor de appType sea igual a "desktop", como se muestra en la Figura 1.

Ventana de configuración de punto de interrupción con una expresión condicional
Figura 1. Ventana de configuración de punto de interrupción con una expresión condicional

Al utilizar los puntos de interrupción con una expresión condicional, se reducen los pasos manuales necesarios para conseguir que la aplicación se encuentre en el estado correcto para la depuración.

Configuración de excepciones

Como desarrollador, sabrá que las excepciones se pueden producir mientras la aplicación está en ejecución. En muchos casos, será necesario tener en cuenta la posibilidad de que algo vaya mal mediante la adición de instrucciones try/catch. Por ejemplo, cuando una aplicación recupera información mediante una llamada de red, dicha llamada puede generar una excepción si el usuario no tiene una conexión de red operativa o si el servidor no responde. En este caso, la solicitud de red debe situarse dentro de una instrucción try y, si se produce una excepción, la aplicación debe mostrar al usuario un mensaje de error adecuado. Si se produce un error en la solicitud cuando espera que funcione (por ejemplo, porque la dirección URL no tiene el formato correcto en el código), podría pensar que una buena idea sería buscar en el código un lugar en el que establecer un punto de interrupción o quitar instrucciones try/catch para que el depurador interrumpa la ejecución en la excepción no controlada.

No obstante, el enfoque más eficaz es configurar el depurador para que interrumpa la ejecución cuando se genere la excepción mediante el diálogo Configuración de excepciones; esto permite que el depurador se establezca de forma que interrumpa la ejecución cuando se generen todas las excepciones o solo las de un tipo determinado. En las versiones anteriores de Visual Studio, los comentarios indicaban que el diálogo Configuración de excepciones tardaba demasiado en abrirse y tenía una funcionalidad de búsqueda demasiado básica. En consecuencia, en Visual Studio 2015, el antiguo diálogo Configuración de excepciones se ha reemplazado por la nueva ventana Configuración de excepciones que se abre al instante y ofrece la característica de búsqueda rápida y coherente que podría esperar, como se muestra en la Figura 2.

La ventana Configuración de excepciones de Visual Studio 2015 con una búsqueda de todos los tipos que contengan "Web"
Figura 2. La ventana Configuración de excepciones de Visual Studio 2015 con una búsqueda de todos los tipos que contengan "Web"

Herramientas de rendimiento durante la depuración

Los usuarios finales esperan que el software sea cada vez más rápido y tenga una mayor capacidad de respuesta, por lo que si se ofrece a los usuarios interfaces de usuario lentas o que estén continuamente cargando, puede afectar negativamente a su retención y satisfacción. El tiempo es valioso y cuando los usuarios tienen que elegir entre varias opciones de aplicaciones con funcionalidades similares, elegirán la que ofrezca la mejor experiencia de usuario.

Sin embargo, al escribir software, a menudo se deja de lado la optimización proactiva del rendimiento y en su lugar se siguen prácticas recomendadas, con la esperanza de que la aplicación sea suficientemente rápida. Los motivos principales son que requiere tiempo y que es complejo medir el rendimiento, y puede ser incluso más complicado encontrar formas de mejorarlo. Para ayudar con esta tarea, el equipo de diagnósticos de Visual Studio integró en Visual Studio 2015 un conjunto de herramientas de rendimiento directamente en el depurador, denominadas Sugerencias de rendimiento (PerfTips), y la ventana Herramientas de diagnóstico. Estas herramientas pueden ayudarle a obtener información sobre el rendimiento del código como parte de la depuración habitual, de forma que pueda detectar los problemas antes y tomar decisiones de diseño en base a la información que le permita crear desde cero la aplicación teniendo en cuenta el rendimiento.

Una forma sencilla de comprender el rendimiento de la aplicación es simplemente recorrerla paso a paso con el depurador para conocer cuánto tarda cada línea de código en ejecutarse. Lamentablemente, no es algo demasiado científico, ya que depende de la capacidad para percibir diferencias. Por lo tanto, es difícil percibir la diferencia entre una operación que tarde 25 ms frente a otra que tarde 75 ms. Como alternativa, puede modificar el código para agregar temporizadores que capturen información precisa, que tiene el inconveniente de tener que cambiar código.

Las sugerencias de rendimiento resuelven esta situación mostrando cuánto tardó en ejecutarse el código, al indicar a la derecha de la línea actual el tiempo en milisegundos que había transcurrido cuando se detuvo el depurador, como se muestra en la Figura 3. Las sugerencias de rendimiento muestran el tiempo que tarda la aplicación en ejecutarse entre dos estados de interrupción cualesquiera del depurador. Esto significa que ambos funcionan cuando se recorre paso a paso el código y se ejecuta hasta puntos de interrupción.

Sugerencia de rendimiento que muestra el tiempo transcurrido en la ejecución de la llamada a una función.
Figura 3. Sugerencia de rendimiento que muestra el tiempo transcurrido en la ejecución de la llamada a una función

Echemos un vistazo a un breve ejemplo de cómo puede ayudar una sugerencia de rendimiento a conocer cuánto tarda el código en ejecutarse. Tiene una aplicación que carga archivos del disco cuando el usuario hace clic en un botón y luego los procesa como corresponda. Las expectativas son que solo tarde unos milisegundos en cargar los archivos del disco; sin embargo, mediante el uso de sugerencias de rendimiento, puede comprobar que tarda considerablemente más. En función de esta información, puede modificar el diseño de la aplicación de forma que no dependa de la carga de todos los archivos cuando el usuario haga clic en el botón, en un momento anterior del ciclo de desarrollo y antes de que el cambio sea demasiado costoso. Para obtener más información sobre las sugerencias de rendimiento, visite aka.ms/perftips.

La ventana Herramientas de diagnóstico muestra un historial del uso de memoria y CPU de la aplicación y todos los eventos de interrupción del depurador (puntos de interrupción, pasos, excepciones e interrumpir todo). La ventana ofrece tres pestañas: Eventos, Uso de memoria y Uso de CPU. En la pestaña Eventos se muestra un historial de todos los eventos de interrupción del depurador, lo que implica que contiene un registro completo de todos los valores de sugerencias de rendimiento. Además, con la versión Enterprise de Visual Studio 2015, contiene todos los eventos de IntelliTrace (que se tratan más adelante en este artículo). En la Figura 4 se muestra la pestaña Eventos en Visual Studio 2015 Enterprise. Por otra parte, si se actualiza la información de CPU y memoria durante la sesión de depuración, se tiene la capacidad de ver las características de CPU y memoria de secciones concretas del código. Por ejemplo, puede ejecutar una llamada a un método e inspeccionar cómo cambian los gráficos que miden el impacto de ese método concreto.

La ventana Herramientas de diagnóstico con la pestaña Eventos seleccionada
Figura 4. La ventana Herramientas de diagnóstico con la pestaña Eventos seleccionada

El gráfico de memoria permite ver el uso total de memoria de la aplicación y detectar tendencias en el uso de memoria de la aplicación. Por ejemplo, el gráfico podría mostrar una tendencia de incremento continua que indicaría que la aplicación está teniendo pérdidas de memoria y podría terminar bloqueándose. Comenzaré echando un vistazo a cómo funciona en .NET Framework y después explicaré la experiencia con C++.

Cuando se depura .NET Framework, el gráfico muestra cuándo se producen recolecciones de elementos no utilizados (GC), así como la memoria total; esto ayuda a identificar situaciones en las que el uso de memoria general de la aplicación está a un nivel aceptable, pero el rendimiento de la aplicación puede resentirse debido a GC frecuentes (que normalmente se deben a la asignación de demasiados objetos de corta duración). La pestaña Uso de memoria permite capturar instantáneas de los objetos en memoria en un momento determinado mediante el botón Tomar instantánea. También ofrece la posibilidad de comparar dos instantáneas distintas, que es la forma más fácil de identificar una pérdida de memoria. Cuando capture una instantánea, siga utilizando la aplicación durante un período de tiempo de una forma que considere que sea neutral en cuanto a memoria y, después, capture una segunda instantánea. En la Figura 5 se muestra la herramienta de memoria con dos instantáneas de .NET.

Pestaña Uso de memoria de la ventana Herramientas de diagnóstico con dos instantáneas
Figura 5. Pestaña Uso de memoria de la ventana Herramientas de diagnóstico con dos instantáneas

Cuando haga clic en una instantánea, se abre una segunda ventana denominada Vista del montón, que muestra los detalles de los objetos que estén en memoria, incluidos el número total y su superficie de memoria. En la mitad inferior de la Vista del montón se muestra lo que contiene referencias a los objetos e impide que se puedan recolectar como elementos no utilizados (se conocen como rutas a raíz), así como el resto de tipos a los que el tipo seleccionado está haciendo referencia en la pestaña Tipos a los que se hace referencia. En la Figura 6 se muestra la Vista del montón con las diferencias entre las dos instantáneas.

Vista del montón de instantánea en la que se muestran las diferencias entre dos instantáneas de .NET
Figura 6. Vista del montón de instantánea en la que se muestran las diferencias entre dos instantáneas de .NET

La herramienta de memoria de C++ realiza un seguimiento de las asignaciones y desasignaciones de memoria para conocer lo que está en memoria en un momento determinado. Para ver los datos, use el botón Tomar instantánea para crear un registro de la información de asignación de ese instante en el tiempo. Las instantáneas también pueden compararse entre sí para ver cómo ha cambiado la memoria entre las dos, lo que permite que sea mucho más fácil realizar un seguimiento de las pérdidas de memoria de las rutas del código que espera liberar completamente en memoria. Cuando selecciona una instantánea para verla, la Vista del montón le muestra una lista de tipos con sus tamaños y, en caso de que se comparen dos instantáneas, las diferencias entre esos números. Cuando ve un tipo con un consumo de memoria que le gustaría comprender mejor, elija ver las instancias de ese tipo. La vista de instancias muestra el tamaño de cada instancia, cuánto tiempo ha estado activa en memoria y la pila de llamadas que asignó la memoria. En la Figura 7 se muestra la vista de instancias.

Vista del montón de la memoria de C++ donde se muestra la vista Instancias con la pila de asignación de llamadas
Figura 7. Vista del montón de la memoria de C++ donde se muestra la vista Instancias con la pila de asignación de llamadas

En el gráfico de CPU se muestra el consumo de CPU de la aplicación como un porcentaje de todos los núcleos de la máquina. Esto significa que resulta útil para identificar operaciones que provocan picos innecesarios en el consumo de CPU y que puede ser de utilidad para identificar operaciones que no estén aprovechando completamente la CPU. Considere un ejemplo de procesamiento de una gran cantidad de datos donde cada registro se puede procesar de forma independiente. Cuando se depura la operación, observará que el gráfico de CPU de una máquina con cuatro núcleos se sitúa ligeramente por debajo del 25 %. Esto indica que existe la posibilidad de ejecutar de forma paralela el procesamiento de datos en todos los núcleos de la máquina, de forma que se obtenga un rendimiento más rápido de la aplicación.

En Visual Studio 2015 Update 1, el equipo de diagnósticos de Visual Studio fue un paso más allá y agregó un perfil de CPU integrado en el depurador a la pestaña Uso de CPU, donde se muestra una descomposición de las funciones de la aplicación que están usando la CPU, como se ilustra en la Figura 8. Por ejemplo, hay código que valida mediante una expresión regular que una dirección de correo electrónico que escriba el usuario tenga un formato válido. Cuando se especifica una dirección de correo electrónico válida, el código se ejecuta extremadamente rápido; sin embargo, si se escribe una dirección de correo electrónico con un formato incorrecto, la sugerencia de rendimiento muestra que puede tardar cerca de dos segundos en determinar que la dirección no es válida. Si observa la ventana Herramientas de diagnóstico, verá que hubo un pico de CPU durante ese momento. Después, si observa el árbol de llamadas de la pestaña Uso de CPU, verá que la coincidencia de la expresión regular es lo que está consumiendo la CPU, que también se muestra en la Figura 8. Resulta que las expresiones regulares de C# tienen un inconveniente: si no son capaces de encontrar una coincidencia para instrucciones complejas, el costo de procesar la cadena entera puede ser elevado. Si usa las sugerencias de rendimiento y la herramienta de uso de CPU de la ventana Herramientas de diagnóstico, podrá determinar rápidamente que el rendimiento de la aplicación no será aceptable en todos los casos en los que se utilice la expresión regular. Por tanto, podrá modificar el código para usar en su lugar operaciones de cadena estándares, que ofrecerán unos resultados de rendimiento muy superiores cuando se especifiquen datos incorrectos. Esto podría haber sido un error costoso de corregir más tarde, especialmente si se hubiera llegado a la fase de producción. Afortunadamente, las herramientas integradas en el depurador han permitido que el diseño cambiase durante el desarrollo para garantizar un rendimiento coherente. Para obtener más información sobre la ventana Herramientas de diagnóstico, vaya a aka.ms/diagtoolswindow.

Pestaña Uso de CPU donde se muestra el consumo de CPU de una operación de coincidencia de una expresión regular
Figura 8. Pestaña Uso de CPU donde se muestra el consumo de CPU de una operación de coincidencia de una expresión regular

Después, echemos un vistazo a algunas de las mejoras que se realizaron específicamente para la depuración de .NET.

Compatibilidad con expresiones lambda en las ventanas Inspección e Inmediato.

Las expresiones lambda (como LINQ) son una forma habitual e increíblemente potente de trabajar de forma rápida con colecciones de datos. Permiten que se realicen operaciones complejas con una única línea de código. A menudo, querrá realizar pruebas sobre cambios en las expresiones de las ventanas del depurador o utilizar LINQ para consultar una colección en lugar de expandirla manualmente en el depurador. Como ejemplo, considere una situación en la que la aplicación realice consultas en una colección de elementos y devuelva cero resultados. Está seguro de que existen elementos que coinciden con los criterios deseados, por lo que comienza a consultar la colección para extraer los elementos distintos de la lista. Los resultados confirman que existen elementos que coinciden con los criterios deseados, pero parece que hay una discordancia con el uso de mayúsculas de las cadenas; aun así, no le preocupa si las mayúsculas y minúsculas coinciden exactamente. Su hipótesis es que es necesario modificar la consulta para omitir el uso de mayúsculas cuando se realiza la comparación de cadenas. La forma más sencilla de comprobar esa hipótesis es escribir la nueva consulta en las ventanas Inspección o Inmediato y ver si devuelven los resultados esperados, como se muestra en la Figura 9.

Lamentablemente, en las versiones de Visual Studio anteriores a 2015, si se especifica una expresión lambda en una ventana de depurador, se generará un mensaje de error. Por tanto, para abordar esta popular solicitud de característica, se agregó compatibilidad para el uso de expresiones lambda en las ventanas del depurador.

Ventana Inmediato con dos expresiones lambda evaluadas
Figura 9. Ventana Inmediato con dos expresiones lambda evaluadas

Mejoras de Editar y continuar en .NET

Una de las características de productividad de depuración favoritas en Visual Studio es Editar y continuar. Editar y continuar permite cambiar el código mientras está detenido en el depurador, para después aplicar la edición sin necesidad de detener la depuración, volver a compilar y ejecutar la aplicación hasta la misma ubicación a fin de comprobar que el cambio corrigió el problema. No obstante, una de las cosas más frustrantes que puede suceder cuando se usa Editar y continuar es realizar la edición, intentar reanudar la ejecución y ver un mensaje que indica que la edición que se ha realizado no se puede aplicar durante la depuración. Esto se estaba convirtiendo en un problema cada vez más habitual a medida que el marco continuaba agregando características de lenguaje que Editar y continuar no podía admitir (por ejemplo, expresiones lambda y métodos asincrónicos).

Para mejorarlo, Microsoft agregó compatibilidad con tipos de edición anteriormente no admitidos, que aumenta de forma significativa el número de veces que se pueden aplicar ediciones correctamente durante la depuración. Las mejoras incluyen la capacidad de modificar expresiones lambda, editar métodos anónimos y asincrónicos, trabajar con tipos dinámicos y modificar características de C# 6.0 (como la interpolación de cadenas y los operadores condicionales nulos). Para ver una lista completa de las ediciones admitidas, visite aka.ms/dotnetenc. Si realiza una edición y recibe un mensaje de error que indica que no se pudo aplicar la edición, asegúrese de comprobar la lista de errores, ya que el compilador incluye información adicional sobre el motivo por el que no se pudo compilar la edición mediante Editar y continuar.

Entre las mejoras adicionales de Editar y continuar, se incluye la compatibilidad con aplicaciones que utilizan CoreCLR x86 y x64, lo que implica que se puede usar para la depuración de aplicaciones de Windows Phone en el emulador, y compatibilidad para la depuración remota.

Nueva experiencia de IntelliTrace

IntelliTrace ofrece información histórica sobre la aplicación para ayudar a reducir las conjeturas sobre la depuración en la edición Enterprise y llevarle a las partes relevantes del código más rápido y con menos sesiones de depuración. Se ha agregado un conjunto completo de mejoras a IntelliTrace para que resulte más fácil de usar que nunca. Las mejoras incluyen una escala de tiempo que muestra en qué momento se produjeron los eventos, la capacidad de ver eventos en tiempo real, compatibilidad con puntos de seguimiento e integración dentro de la ventana Herramientas de diagnóstico.

La escala de tiempo permite comprender en qué momento se produjeron los eventos e identificar grupos de eventos, que podrían estar relacionados. Los eventos se muestran a tiempo real en la pestaña Eventos; en las versiones anteriores era necesario especificar un estado de interrupción en el depurador para ver los eventos que IntelliTrace recopiló. La integración de puntos de seguimiento permite crear eventos de IntelliTrace mediante la funcionalidad de depurador estándar. Finalmente, la integración de la ventana Herramientas de diagnóstico sitúa los eventos de IntelliTrace en contexto con información de rendimiento, lo que permite usar la valiosa información de IntelliTrace para comprender el motivo de los problemas de memoria y rendimiento, mediante la correlación de la información en una escala de tiempo común.

Cuando detecta un problema en la aplicación, normalmente piensa en una hipótesis sobre dónde debería comenzar a investigar, establece un punto de interrupción y ejecuta de nuevo el escenario. Si el problema resulta no estar en esa ubicación, necesita pensar en una nueva hipótesis sobre cómo llegar a la ubicación correcta del depurador y comenzar de nuevo el proceso. El objetivo de IntelliTrace es mejorar este flujo de trabajo, eliminando la necesidad de volver a ejecutar el escenario.

Considere el ejemplo anterior de este artículo en el que una llamada de red no se realiza correctamente de forma inesperada. Sin IntelliTrace, es necesario ver el error la primera vez, habilitar el depurador para interrumpir la ejecución cuando se genera la excepción y después ejecutar de nuevo el escenario. Con IntelliTrace, cuando detecta el error, lo único que debe hacer es consultar la pestaña Eventos de la ventana Herramientas de diagnóstico. La excepción aparece como un evento; selecciónelo y haga clic en Activar depuración histórica. Después, navegará atrás en el tiempo hasta la ubicación del código fuente en que se produjo la excepción, se mostrará información de la excepción en las ventanas Variables locales y Automático, y se rellenará la ventana Pila de llamadas con la pila de llamadas en el momento en que se produjo la excepción, como se muestra en la Figura 10.

Visual Studio en el modo de depuración histórica en la ubicación en que se generó una excepción
Figura 10. Visual Studio en el modo de depuración histórica en la ubicación en que se generó una excepción

Para concluir, echemos un vistazo a algunas de las mejoras más destacadas que se han realizado para la depuración de C++ en Visual Studio 2015.

Editar y continuar en C++

Como se mencionó anteriormente, Editar y continuar es una característica de productividad que permite modificar el código mientras se encuentra detenido en el depurador y después aplicar las ediciones cuando se reanude la ejecución, sin necesidad de detener la depuración para volver a compilar la aplicación modificada. En versiones anteriores, Editar y continuar en C++ tenía dos importantes limitaciones. La primera es que solo admitía aplicaciones x86. La segunda es que al habilitar Editar y continuar, Visual Studio utilizaba el depurador de Visual Studio 2010 C++, que no disponía de nueva funcionalidad, como la compatibilidad con las visualizaciones de datos Natvis (vea aka.ms/natvis). En Visual Studio 2015, estas dos limitaciones han desaparecido. La característica Editar y continuar está habilitada de forma predeterminada para los proyectos de C++ para aplicaciones x86 y x64, e incluso puede funcionar cuando se adjuntan a procesos y depuración remota.

Compatibilidad con iOS y Android

A medida que el mundo cambia a una mentalidad en que se da prioridad a lo móvil, muchas organizaciones se están encontrando con la necesidad de crear aplicaciones móviles. Con la diversificación de plataformas, C++ es una de las pocas tecnologías que se puede usar en cualquier dispositivo y sistema operativo. Muchas grandes organizaciones están usando código C++ compartido para la lógica de negocios común que quieren reutilizar en una amplia variedad de ofertas. Para facilitar esta tarea, Visual Studio 2015 ofrece herramientas que permiten que los desarrolladores móviles tengan como destinos iOS y Android directamente desde Visual Studio. Esto incluye la conocida experiencia de depuración de Visual Studio que los desarrolladores usan en su trabajo diario con C++ en Windows.

Conclusión

El equipo de diagnósticos de Visual Studio está entusiasmado con la enorme gama de funcionalidades que se han agregado a la experiencia de depuración de Visual Studio 2015. Todo lo que se trata en este artículo con la excepción de IntelliTrace está disponible en la edición Community de Visual Studio 2015.

Puede seguir el progreso del equipo y las mejoras futuras en el blog del equipo, que puede encontrar en aka.ms/diagnosticsblog. Le animo a que pruebe las características que se han explicado en este artículo y envíe comentarios al equipo sobre cómo pueden continuar mejorando Visual Studio para cubrir sus necesidades de depuración. Puede enviar comentarios y preguntas en las publicaciones del blog o enviar comentarios directamente a través de Visual Studio, mediante el icono Enviar comentarios que se encuentra en la parte superior derecha del IDE.


Andrew Hall* es el jefe de programa responsable del equipo de diagnósticos de Visual Studio que crea las experiencias de IntelliTrace, creación de perfiles y depuración principal, así como el emulador de Android para Visual Studio. A lo largo de los años, Hall ha trabajado directamente en el depurador, el generador de perfiles y las herramientas de análisis de código de Visual Studio.*

Gracias a los siguientes expertos técnicos por revisar este artículo: Angelos Petropoulos, Dan Taylor, Kasey Uhlenhuth y Adam Welch