¿Por qué no se lanza la excepción de operación de hilo cruzado al ejecutar exe en bin \ Debug

Estaba depurando una aplicación y en alguna parte del código, un hilo intenta llegar a un cuadro de lista que fue creado por otro hilo. Al intentar acceder al cuadro de lista, la aplicación arroja una “Operación entre hilos no válida: Control ‘ cuadro de lista ‘ al que se accede desde un hilo que no sea el hilo en el que se creó” excepción durante la depuración. Sin embargo, cuando ejecuto el resultado de esta aplicación en la carpeta bin \ Debug, no obtengo un diálogo de excepción y puedo ver que se accede al cuadro de lista desde el subproceso no propietario, por lo que creo que hay una diferencia de comportamiento aquí , no solo una excepción suprimida. Puedo superar esta excepción en la depuración con la siguiente línea en el evento form_load

Control.CheckForIllegalCrossThreadCalls = false; 

¿Pero cuál es la razón detrás de este comportamiento diferente?

Sí, esto solo se verifica cuando se conecta un depurador. Esto fue necesario porque había muchos códigos .NET 1.x que violaban esta regla. No es obvio.

El problema más grande es que dicho código se salió con la suya. O bien por suerte, sin pensar demasiado en los ocasionales problemas de pintura o pensando que abortar la aplicación cuando se estancaba y reiniciarla una vez al día era aceptable. Porque el progtwigdor no tenía ninguna esperanza real de descubrir el problema sin un diagnóstico.

A Microsoft le preocupa mucho la compatibilidad con versiones anteriores, incluso si es incompatible. La solución es excelente, aunque a veces es incorrecta (Mostrar (propietario) está marcada cuando no debería). Y a veces pasa por alto para verificar cuándo es código en el marco que viola la regla. Lo que sucede cuando la dependencia del hilo es indirecta. Los casos más comunes son la actualización del origen de datos de un control vinculado a datos en un hilo de trabajo (¡Desvincular primero!) Y el uso de un control que escucha el evento SystemEvents.UserPreferenceChanged (¡no cree UI en un segundo hilo!)


Como referencia, el código relevante está presente en el constructor estático de la clase Control:

 static Control() { //... checkForIllegalCrossThreadCalls = Debugger.IsAttached; //... }