2008-08-13 7 views

Respuesta

10

Porque puede terminar fácilmente con un interbloqueo (entre otros problemas).

Por ejemplo, su hilo secundario podría estar intentando actualizar el control de la IU, pero el control de IU estará esperando que se libere un recurso bloqueado por el hilo secundario, por lo que ambos hilos terminan esperando el uno al otro para terminar. Como otros han comentado, esta situación no es exclusiva del código de UI, pero es particularmente común.

En otros lenguajes, como C++, puede probar y hacer esto (sin excepción lanzándose como en WinForms), pero su aplicación puede congelarse y dejar de responder si se produce un interbloqueo.

Dicho sea de paso, puede decir fácilmente el subproceso de interfaz de usuario que desea actualizar un control, simplemente cree un delegado, luego llame al método BeginInvoke (asincrónico) en ese control pasándolo a su delegado. P.ej.

myControl.BeginInvoke(myControl.UpdateFunction); 

Esto es el equivalente a hacer un C++/MFC PostMessage de un subproceso de trabajo

+3

No estoy seguro de por qué se aceptó esta respuesta. Esta simplemente no es la respuesta correcta. Los bloqueos pueden ocurrir siempre que tenga múltiples hilos. No hay nada inherente en los programas de GUI que los hace más propensos a suceder. Además, pueden suceder fácilmente incluso si usa BeginInvoke(). La respuesta de Brian Ensink es la correcta. – mhenry1384

+1

-1: la espera de recursos bloqueados no es el problema. El problema son las condiciones de carrera, que existen en grandes cantidades en cualquier código que no fue diseñado para ser utilizado en entornos de subprocesos múltiples. Incluso puede verificar esto configurando [CheckForIllegalCrossThreadCalls] (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls (VS.80) .aspx) en falso, y observe el punto muerto -operación libre, hasta que ocurra algo gracioso. –

1

Es así que no tiene dos cosas tratando de actualizar el control al mismo tiempo. (Esto podría suceder si la CPU cambia al otro hilo en medio de una escritura/lectura) La misma razón por la que necesita usar mutexes (o alguna otra sincronización) al acceder a variables compartidas entre múltiples hilos.

Editar:

En otros lenguajes como C++ usted es libre para tratar de hacer esto (sin excepción ser lanzado como en WinForms), pero que va a terminar aprendiendo el disco ¡camino!

Ahh sí ... me cambio entre C/C++ y C# y, por tanto, era un poco más genérica a continuación, que debería haber sido, lo siento ... Él es correcta, puede hacer esto en C/C++, pero volverá a morderte!

2

vuelta en 1.0/1.1 no es una excepción fue lanzado durante la depuración, lo que tienes en cambio, fue un escenario de tiempo de ejecución colgando intermitente . ¡Bonito! :) Por lo tanto, con 2.0 hicieron que este escenario arrojara una excepción y con razón.

La razón real de esto es probablemente (como afirma Adam Haile) algún tipo de problema de concurrencia/locky. Tenga en cuenta que la API normal .NET (como TextBox.Text = "Hello";) envuelve los comandos ENVIAR (que requieren acción inmediata) que pueden crear problemas si se realizan en un hilo separado del que ejecuta la actualización. El uso de Invoke/BeginInvoke utiliza un POST que pone en cola la acción.

Más información sobre ENVÍO y POST here.

1

También sería necesario implementar la sincronización dentro de las funciones de actualización que son sensibles a ser llamadas simultáneamente. Hacer esto para los elementos de la interfaz de usuario sería costoso tanto para la aplicación como para el sistema operativo, y sería completamente redundante para la gran mayoría del código.

Algunas API proporcionan una forma de cambiar la propiedad actual de subprocesos de un sistema para que pueda actualizar (o permanentemente) sistemas de otros subprocesos sin necesidad de recurrir a la comunicación entre subprocesos.

0

Creo que esta es una pregunta brillante, y creo que hay una necesidad de una mejor respuesta.

Seguramente la única razón es que hay algo en un marco en algún lugar que no es muy seguro para subprocesos. ¿Es un problema con .NET o Win32? ¿Y por qué no hay un empuje para arreglar la fuente en lugar de imponer lo que, para mí, parece una desagradable tarea?

¿Alguien sabe dónde está el verdadero problema subyacente?

23

creo que este es un brillante pregunta - y creo que existe la necesidad de una mejor respuesta.

Seguramente la única razón es que hay es algo en un marco en algún lugar que no es muy seguro para subprocesos.

Ese "algo" es casi cada miembro de instancia en cada control en System.Windows.Forms.

La documentación de MSDN para muchos controles en System.Windows.Forms, si no todos ellos, digamos "Cualquier miembro público estático (Shared en Visual Basic) de este tipo es seguro para subprocesos. estar seguro de subprocesos ".

Esto significa que los miembros de instancia, tales como TextBox.Text {get; set;} no son reentrante.

Hacer que cada uno de esos miembros de la instancia sea seguro para los hilos puede introducir una sobrecarga que la mayoría de las aplicaciones no necesitan. En cambio, los diseñadores del framework .Net decidieron, y creo que correctamente, que la carga de sincronizar el acceso a los controles de formularios desde múltiples hilos debería ser puesta en el programador.

[Editar]

Aunque esta pregunta sólo se pregunta "por qué" aquí hay un enlace a un artículo que explica "cómo":

Cómo: Realiza llamadas Hilo de seguridad a Windows Forms en MSDN

http://msdn.microsoft.com/en-us/library/ms171728.aspx

+1

Es completamente posible reentrada pero no es seguro para subprocesos. Considera (f) => {x + = 1; f (x); x - = 1; } que está bien hasta que se desborde si f (x) vuelve a entrar en la lambda en un hilo, pero las carreras en x si multiproceso. –

7

Aunque suene respuesta Johns razonable no es correcta. De hecho, incluso cuando usas Invoke, todavía no estás seguro y no te encuentras en situaciones de bloqueo. Cuando se trata de eventos disparados en un hilo de fondo, usar Invoke puede incluso llevar a este problema.


La verdadera razón tiene más que ver con las condiciones de carrera y pone de nuevo en los tiempos antiguos Win32. No puedo explicar los detalles aquí, las palabras clave son bombas de mensajes, eventos WM_PAINT y las diferencias sutiles entre "ENVIAR" y "POST".


Más información se puede encontrar aquí here y here.

0

Hmm No estoy muy seguro, pero creo que cuando tenemos controles de progreso como barras de espera, barras de progreso, podemos actualizar sus valores desde otra secuencia y todo funciona bien sin problemas técnicos.

Cuestiones relacionadas