2012-05-04 13 views
13

Veo una gran cantidad de hilos en google/aquí en la actualización de un elemento de la interfaz de usuario de otro hilo.¿Se puede acceder a los elementos de la interfaz de usuario de otra conversación? (no establecer)

¿Qué sucede si solo quiero obtener el valor de una casilla de verificación?

¿Puedo hacer esto sin tener que hacer nada especial?

+0

puede usar los delegados para hacer eso – jorne

+4

@CodeCaster Solo intente y vea lo que funciona generalmente no le proporciona código seguro para subprocesos. – hvd

+1

@hvd: Pero satisface todas las preguntas planteadas _aquí_. –

Respuesta

18

Editar: Parece que tengo que recuperar lo que escribí antes. Intentado el siguiente:

añadido un cuadro de texto denominado myTextBox y trató de recuperar el valor de la propiedad Text:

Thread t = new Thread(
    o => 
    { 
     Thread.Sleep(2000);      
     string value = myTextBox.Text; 
     Thread.Sleep(2000); 
    }); 
t.Start(); 

Y parece que la aplicación (WPF) se bloquea después de 2 segundos. Utilizando el despachador funciona:

Thread t = new Thread(
    o => 
    { 
     Thread.Sleep(2000); 
     myTextBox.Dispatcher.BeginInvoke(
      (Action)(() => { string value = myTextBox.Text; })); 
     Thread.Sleep(2000); 
    }); 
t.Start(); 

Por lo tanto, usted todavía tiene que pasar por el hilo despachador al leer los valores de los componentes GUI, al menos en WPF.

Segunda edición: Esto se pone mejor. Al parecer, repetir el experimento para WinForms clásicos revela que funciona para leer la propiedad Text sin usar Invoke/BeginInvoke. Curiosamente, parece que también la configuración de la propiedad funciona bien (sin invocar), aunque apostaría a que no es seguro para subprocesos y la aplicación no se queja por alguna razón.

En pocas palabras: Es una buena idea en cualquier caso de usar el despachador al interactuar con los componentes de la GUI de otros hilos, ya que garantiza las lecturas/escrituras son serializado a un solo hilo y por lo que no tienen hilos de seguridad cuestiones.

+0

+1 para publicar el experimento. –

+0

"la aplicación no se queja" -> ¿Se ejecuta en modo de lanzamiento tal vez? –

+0

@Henk Holterman: He intentado con Release y Debug y parece que no noto ninguna diferencia. – Tudor

0

simplemente lea el valor como lo hace normalmente. Solo para actualizar el control, debe cambiar al hilo de GUI.

+1

Probablemente funciona con CheckBox.Checked 'porque es una propiedad booleana. Como otros han publicado, obtener textbox.Text es mucho más dudoso. –

2

Podría, pero estrictamente, no sería seguro para subprocesos. Por ejemplo, si la propiedad Obtener código constaría de varias operaciones, el subproceso de interfaz de usuario podría actuar en el tiempo medio, a mitad de camino durante la operación Obtener, lo que provocaría resultados inesperados.

7

¿Se puede acceder a los elementos de la IU de otra conversación? (no te pongas)

Este es el trato. Los elementos de la interfaz de usuario tienen requisitos de afinidad de hilos muy estrictos. Esto significa que solo puede acceder al elemento desde el hilo que lo hospeda. Esto incluye todo tipo de accesos incluyendo lecturas simples.

Puede funcionar bien para obtener propiedades simples, pero su seguridad percibida sería un resultado accidental de la forma en que se implementó ese control en particular. Dado que las instancias Control tienen afinidad con las cadenas de caracteres, podrían utilizar técnicas de almacenamiento local de subprocesos para guardar parte de su estado, lo que, por supuesto, no sería compatible con una cadena de caracteres diferente. ¿O qué pasa si el valor que está tratando de leer está medio vacío? No habría forma de sincronizar el acceso a esa lectura, ya que la escritura puede estar ocurriendo dentro de un código sobre el que no tiene control.Y todavía esto está ignorando los problemas sutiles de la barrera de la memoria que pueden surgir.

De nuevo, si parece funcionar, apúntelo como un accidente. El acceso a los elementos de la interfaz de usuario de un hilo que no sea el que los aloja es una receta para el desastre. Las cosas pueden fallar impredeciblemente y espectacularmente.


Hay muy pocas excepciones a esta regla. Usar los métodos ISynchronizeInvoke es una de esas excepciones.

Cuestiones relacionadas