2009-06-18 8 views
5

Tengo un problema de depuración multiproceso bastante serio. Tengo algún tipo de problema de tiempo al interactuar con un dispositivo serie, y necesito rastrearlo. Tengo tres hilos:Depuración con subprocesos en C# y vs2008

  1. El hilo principal de las actualizaciones de la interfaz de usuario. El usuario puede cambiar un parámetro del dispositivo, o muchos a la vez, eligiendo un ajuste preestablecido.
  2. El hilo de comprobación de estado que consulta para asegurarse de que el dispositivo todavía está conectado. Si el usuario apaga el dispositivo o el dispositivo se interactúa de forma interesante, los cambios de estado deben reflejarse en la IU.
  3. El hilo que lee el puerto serie donde responde el dispositivo.

Mi problema en realidad tiene que ver con la depuración de esta situación. Parece que cada línea que tengo en cada hilo tiene que tener un punto de interrupción para poder depurarla; si rompo un hilo, el depurador no pasará por ese hilo. Entiendo que los otros subprocesos continuarán actualizándose, pero ¿el subproceso en el que me encuentro no debería ejecutarse normalmente en el depurador, es decir, pasar de una línea a la siguiente? Entonces, podría usar la pestaña 'hilos' para alternar entre hilos.

Menciono que estoy en WPF porque no sé si eso cambia la situación; tal vez sí, tal vez no. El hilo de comprobación de estado es parte de un control de interfaz de usuario, porque el estado solo debe verificarse mientras la interfaz de usuario está activa. Ese control está en una biblioteca distinta de la aplicación principal.

+0

Se eliminaron las referencias de WPF porque no están realmente relacionadas con WPF, solo depuración MT genérica. –

+0

Desafortunadamente, me he dado cuenta de que el vs2008 ha comenzado a actuar muy, muy (este es solo un comportamiento problemático, otros tienen que ver con el control de fuente y con diferentes configuraciones) que ha sucedido desde que el proyecto migró a WPF. De ahí la inclusión, por si acaso. – mmr

Respuesta

1

Si su código es un paso único de una manera extraña, a veces puede ser causado por un simple archivo roto pdb. Una "reconstrucción de todo" en tu código lo regenerará desde cero y curará cualquier falla.

Otra cosa a tener en cuenta es que detener un hilo en el depurador puede causar todo tipo de sincronización inusual que no vería en una compilación de lanzamiento. Por ejemplo:

  • el puerto de serie siempre seguirá funcionando (en un nivel de hardware/controlador), mientras que ha dejado en un punto de ruptura - la próxima vez que intenta intensificar su código, puede recibir una enorme explosión repentina de datos. Con devoluciones de llamada asíncronas, esto puede ser "interesante".

  • La detención de un hilo perturba el normal del tiempo para que la sincronización de hilo a hilo se pueda atornillar.

7

Cuando el depurador se detiene en un punto de interrupción, de forma predeterminada suspenderá todos los demás subprocesos. Pero cuando pisas o continúas, se reanudan los 3 hilos. Cuando pisa el código, el depurador básicamente establece un punto de interrupción temporal en la siguiente línea y reanuda todos los subprocesos. Los otros 2 pueden tener la oportunidad de correr antes de que se golpee ese punto de ruptura virtual.

Puede congelar los demás hilos durante la depuración

Cuando estás en un punto de interrupción de depuración seleccione | Windows | Hilos. Seleccione los temas que no le interesan y haga clic con el botón derecho, seleccione Congelar. Esto te permitirá enfocarte en el único hilo que estás atravesando.

+0

pero mi punto es que no está llegando a ese punto de interrupción temporal; simplemente continúa alegremente, sin llegar a puntos de ruptura distintos del original. Quiero que los otros hilos se estén ejecutando; Quiero poder ver dónde se portan mal. – mmr

+0

¿Qué sucede cuando se rompe manualmente después de pisar? ¿Se pierde en un método Win32 en alguna parte o se detiene en algún momento más adelante en tu código? –

+0

nunca se detiene, simplemente continúa. – mmr

1

Estoy con Jason, stepping ya no mostrará la verdad.

Le conviene mucho más instrumentar cada línea de código con un método que también incrementa un contador usando Interlocked.Increment y agrega el contador a la salida (un archivo local es el mejor).

El contador es necesario porque el orden de los eventos reales no es siempre el mismo que el de las escrituras en el archivo. Denomine los hilos o use el valor de ID en la salida, también. Utilizo MS Excel para abrir el archivo y colorear todas las filas dependiendo del hilo, de esta manera puedo ver las operaciones de entrelazado muy claramente.

Incluso he escrito una envoltura para bloquear {} qué instrumentos se activan/desactivan cada cerradura.

Los problemas de sincro son terribles para disparar, por lo que le aconsejo que no gaste más de lo que le tomaría refactorizar. Algunas veces es una indicación de que el enfoque que está tomando es subóptimo.

Recuerde usar volátil cuando sea necesario con IO.

Cuestiones relacionadas