c# - ¿Cómo depurar un solo hilo en Visual Studio?
asp.net multithreading (8)
Tengo una solución con algunos proyectos. Hay varios puntos de quiebre en diferentes proyectos. Quiero rastrear el primer hilo golpeado en uno de estos puntos de ruptura y continuar el rastreo de ese solo hilo a pesar de que otros hilos ingresan en los mismos bloques de código.
Sé que esto es posible definiendo una condición en el punto de interrupción, es decir, nombre de hilo = ... o Id de hilo = ... pero mi caso es una aplicación ASP.NET cargada y tan pronto como la adjunto a w3wp.exe
muchos hilos golpearán los puntos de ruptura. Necesito algo como un ThreadLocal<break-point>
.
¿Es posible? ¿Si es así, cómo?
Acabo de lanzar una extensión de Visual Studio 2010+ que hace exactamente lo que estás buscando. Y es gratis :).
Presentación
Esta extensión de Visual Studio agrega dos accesos directos y botones de la barra de herramientas para permitir a los desarrolladores enfocarse fácilmente en subprocesos individuales mientras depuran aplicaciones de subprocesos múltiples.
Reduce drásticamente la necesidad de ir manualmente a la ventana de Subprocesos para congelar / descongelar todos los subprocesos menos el que se debe seguir, y por lo tanto ayuda a mejorar la productividad.
Caracteristicas
Restrinja la ejecución adicional solo al hilo actual. Se congelarán todos los otros hilos. Atajo: CTRL + T + T o botón Copo de nieve. Cambia al siguiente hilo único (basado en ID). Cambiará el hilo actual y congelará todos los otros hilos. Atajo: CTRL + T + J o el botón Siguiente.
Échale un vistazo aquí en la Galería , en la página oficial o en el repositorio de Github .
Congelar / descongelar hilos es una forma incorrecta porque otros hilos no ejecutan ningún código.
La forma más correcta y utilizable es:
- Presione Ctrl + A en la ventana de puntos de interrupción (seleccione todos los puntos de interrupción).
- Haga clic derecho y seleccione "Filtro ...".
- Introduzca "ThreadId = (id de hilo actual)".
En Visual Studio 2015 y más reciente, el proceso es similar:
- Presione Ctrl + A en la ventana de puntos de interrupción (seleccione todos los puntos de interrupción).
- Haga clic derecho y seleccione "Configuración ...".
- Marque "Condiciones" y seleccione "Filtro" en el menú desplegable
- Introduzca "ThreadId = (id de hilo actual)".
Por lo tanto, todos los subprocesos se ejecutan, pero el depurador solo llega al subproceso actual.
Creo que esto es un poco diferente en Visual Studio 2015. Han cambiado algunas cosas en los puntos de interrupción, pero aquí hay cómo aplicar la respuesta aceptada de hzdbyte (arriba):
En el punto de interrupción en el margen de codificación, haga clic con el botón derecho> Condiciones> Cambiar de ''Expresión condicional'' a ''Filtro''. Esto entonces le permite filtrar por ThreadId.
De forma alternativa, en el punto de interrupción en la ventana Puntos de interrupción, haga clic con el botón derecho> Configuración> marque la casilla Condiciones y haga lo anterior.
Esto es lo que hice:
Establezca un punto de interrupción condicional que sabía que solo afectaría al hilo que estaba buscando.
Una vez que llegue el punto de interrupción y se encuentre en el hilo que desea, en la ventana Subprocesos de Visual Studio (mientras se depura, Depurar -> Ventanas -> Hilos), Ctrl + A (para seleccionar todos los hilos), y luego presione Ctrl y haga clic en el hilo que están actualmente en Debe tener todos los subprocesos excepto el que desea depurar seleccionado.
- Haga clic derecho y seleccione "Congelar".
Ahora, Visual Studio solo atravesará el hilo descongelado. Parece ser mucho más lento al hacer esto, presumiblemente porque tiene que recorrer todos los subprocesos congelados, pero aportó algo de cordura a mi depuración de subprocesos múltiples.
Si no desea detener todos los demás subprocesos (quizás está adjuntando 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 los puntos de interrupción automáticamente.
Esto se sugiere en una respuesta a la pregunta de Desbordamiento de pila "Paso a paso" al depurar programas de multiproceso en Visual Studio .
Sin embargo, el enlace solo explica cómo depurar línea por línea. Le sugiero que modifique la macro (si se siente cómodo con ella) para que modifique todos los puntos de interrupción (en un rango de línea dado, por ejemplo) para que se detenga solo en el hilo actual.
Si se generan varios subprocesos como para una aplicación web, la respuesta de @MattFaus no funcionará. Lo que hice en cambio es el siguiente
- Configure un punto de interrupción para interrumpir el hilo en la función que quiero.
- Una vez que el hilo llega al punto de interrupción y está en pausa, elimino el punto de interrupción y continúo la depuración utilizando F8, F10 y F11, para que los otros hilos puedan ejecutarse.
Sugeriría agregar otra instancia de la aplicación en el servidor en vivo, ya sea en el mismo hardware o en una nueva máquina (agruparla) y luego depurar solo esa instancia. No agregaría un punto de interrupción en el código que los usuarios están activando. Si esa 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
. Tenga en cuenta, sin embargo, que esto ralentiza considerablemente su aplicación.
Un enfoque ligeramente diferente que he usado:
- Crea un punto de ruptura normal y deja que sea golpeado
- Busque en la ventana de subprocesos el ID de subproceso administrado que está depurando actualmente
- Haga clic derecho en su punto de interrupción en la ventana de puntos de interrupción y el filtro de selección
- Ingrese ThreadId = xxx donde xxx es el ID de hilo de 2
- Ahora puede depurar sin detener otros subprocesos y sin que lleguen a su punto de interrupción
Esto supone que tiene tiempo para hacer lo anterior antes de que un segundo hilo llegue a su punto de interrupción. Si no y otros subprocesos alcanzan su punto de ruptura antes de que haya hecho lo anterior, puede hacer clic con el botón derecho en la ventana de subprocesos y elegir congelar.