¿Cómo depurar un solo hilo en Visual Studio?

Tengo una solución con algunos proyectos. Hay varios puntos de quiebre en diferentes proyectos. Quiero rastrear el primer hilo golpear uno de estos puntos de ruptura y continuar el seguimiento de ese único hilo a pesar de que otros hilos entren en los mismos bloques de código.

Sé que esto es posible mediante la definición de una condición en el punto de ruptura, es decir, nombre del hilo = … o hilo Id = … pero mi caso es una aplicación ASP.NET cargada y tan pronto como me w3wp.exe a w3wp.exe muchos hilos llegarán a los puntos de ruptura. Necesito algo como un ThreadLocal .

¿Es posible? ¿Si es así, cómo?

Congelar / Descongelar hilos es una forma incorrecta porque otros hilos no ejecutan ningún código.

La forma más correcta y útil es:

  1. Presiona Ctrl + A en la ventana de puntos de interrupción (selecciona todos los puntos de interrupción).
  2. Haga clic derecho y seleccione “Filtrar …”.
  3. Ingrese “ThreadId = (identificación actual del hilo)”.

En Visual Studio 2015 y versiones posteriores, el proceso es similar:

  1. Presiona Ctrl + A en la ventana de puntos de interrupción (selecciona todos los puntos de interrupción).
  2. Haga clic derecho y seleccione “Configuración …”.
  3. Marque “Condiciones” y seleccione “Filtro” en el menú desplegable
  4. Ingrese “ThreadId = (identificación actual del hilo)”.

Por lo tanto, todos los subprocesos se ejecutan, pero el depurador solo acierta en el subproceso actual.

Esto es lo que hice:

  1. Establecí un punto de interrupción condicional que sabía que solo llegaría al hilo que estaba buscando.

  2. Una vez que llega el punto de interrupción y está en el hilo que desea, en la ventana de Visual Studio Threads (durante la depuración, Depurar -> Windows -> Hilos), Ctrl + A (para seleccionar todos los hilos), y luego Ctrl + clic en el hilo están actualmente encendidos Debería tener todos los hilos excepto el que desea depurar seleccionado.

  3. Haz clic con el botón derecho y elige “Congelar”.

Ahora, Visual Studio solo pasará por el hilo descongelado. Parece ser mucho más lento al hacer esto, presumiblemente porque tiene que pasar por todos los hilos congelados, pero trajo un poco de cordura a mi depuración de subprocesos múltiples.

Acabo de lanzar una extensión de Visual Studio 2010+ que hace exactamente lo que está buscando. Y es gratis :).

Presentación

Esta extensión de Visual Studio agrega dos accesos directos y botones de barra de herramientas para permitir a los desarrolladores enfocarse fácilmente en subprocesos individuales mientras se depuran las aplicaciones de múltiples subprocesos.

Reduce drásticamente la necesidad de acceder manualmente a la ventana de Hilos para congelar / descongelar todos los hilos, pero el que se debe seguir y, por lo tanto, ayuda a mejorar la productividad.

Caracteristicas

Restrinja la ejecución adicional al hilo actual solamente. Congelará todos los otros hilos. Atajo: CTRL + T + T o botón copo de nieve. Cambie al siguiente hilo individual (basado en ID). Cambiará el hilo actual y congelará todos los otros hilos. Atajo: CTRL + T + J o botón Siguiente.

Verifíquelo aquí en la Galería , en la página oficial o en el repository de Github .

Un enfoque ligeramente diferente que he usado:

  1. Crea un punto de interrupción normal y deja que sea golpeado
  2. Busque en la ventana de subprocesos el Id. De subproceso administrado que está depurando actualmente
  3. Haga clic con el botón derecho en su punto de interrupción en la ventana de puntos de corte y seleccione el filtro
  4. Ingrese ThreadId = xxx donde xxx es la ID del hilo desde 2
  5. Ahora puede depurar sin detener otros hilos y sin que ellos lleguen a su punto de interrupción

Esto supone que tienes tiempo para hacer lo anterior antes de que un segundo hilo llegue a tu punto de interrupción. Si no, y otros hilos llegan a su punto de interrupción antes de que haya hecho lo anterior, puede hacer clic con el botón derecho en la ventana de hilos y elegir congelar.

Si se generan varios hilos como para una aplicación web, las respuestas de @MattFaus no funcionarán. lo que hice en su lugar es el siguiente

  • Configure un punto de interrupción para interrumpir el hilo en la función que quiero.
  • Una vez que el subproceso llega al punto de interrupción y se pone en pausa, elimino el punto de interrupción y continúo depurando con F8, F10 y F11, para que se puedan ejecutar los otros subprocesos.

Sugiero agregar otra instancia de la aplicación en el servidor activo, ya sea en el mismo hardware o en una máquina nueva (clústerlo) y luego depurar solo esa instancia. No agregaría un punto de interrupción en el código que los usuarios están desencadenando. Si no es una opción, agregaría más rastreo.

Sin embargo, si esto es absolutamente necesario y necesita una estadística de solución, estoy seguro de que podría agregar un punto de interrupción que se rompa solo si la solicitud proviene de su dirección IP. Para ello, agregue un punto de interrupción condicional que inspeccione HttpContext.Request.UserHostAddress . Sin embargo, tenga en cuenta que esto ralentiza considerablemente su aplicación.

Si no desea detener todos los demás hilos (tal vez está conectando el depurador de Visual Studio a una aplicación en ejecución que necesita responder a las solicitudes), puede usar una macro que cree y elimine puntos de interrupción automáticamente.

Esto se sugiere en una respuesta a la pregunta de Stack Overflow “Paso” al depurar progtwigs multiproceso en Visual Studio .

Sin embargo, el enlace solo explica cómo depurar línea por línea. Sugiero que modifiques la macro (si te sientes cómodo con ella) para que modifique todos los puntos de interrupción (en un rango de línea dado, por ejemplo) para detener solo en el hilo actual.

Creo que esto es ligeramente diferente en Visual Studio 2015. Han cambiado algunas cosas en los puntos de interrupción, pero he aquí cómo aplicar la respuesta aceptada de hzdbyte (arriba):

En el punto de corte en el margen de encoding, haga clic con el botón derecho> Condiciones> Cambiar de ‘Expresión condicional’ a ‘Filtro’. Esto luego le permite filtrar por ThreadId.

Alternativamente, en el punto de interrupción en la ventana Puntos de interrupción, haga clic con el botón derecho en> Configuración> marque el cuadro Condiciones y haga lo anterior.