2011-04-01 14 views
22

estoy tratando de leer un ComboBox.text de un hilo que no sea el hilo que se creó el pero estoy consiguiendo el error:¿Cómo leer el combobox de un hilo que no sea el hilo en el que se creó?

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Cross-thread operation not valid: Control 'levelsComboBox' accessed from a thread other than the thread it was created on.

he utilizado .Invoke antes, pero sólo para establecer las propiedades, ¿cómo Lo uso para leer combobox.Text? Porque. Invoke devuelve nulo y necesito una cadena. ¿O hay otra forma de hacerlo sin la invocación?

+0

creo que esto es un duplicado de la [¿Cómo obtener valor de retorno cuando BeginInvoke/Invoke se llama en C#] (http://stackoverflow.com/questions/2214002/how-to-get-return-value-when-begininvoke-invoke-is-called-in-c) –

Respuesta

44

Puede hacerlo de esta manera:

this.Invoke((MethodInvoker)delegate() 
    { 
     text = combobox.Text; 
    }); 
+1

Tengo 2 días buscando esta solución. thnx – Florjon

+0

Funciona muy bien. Me ayudó a implementar el patrón Observer en C#. – Mythul

+0

¡Genial! me ayudó también a las 3 a.m. rascándome la cabeza para recordar esta sintaxis ... –

2

La solución más fácil es utilizar la clase BackgroundWorker para ejecutar trabajos en otro hilo, al tiempo que se puede actualizar la interfaz de usuario (por ejemplo, al informar el progreso o cuando la tarea se ha completado).

17

Aún puede usar Invoke y leerlo en una variable local.

Algo como esto:

string text; 

this.Invoke(new MethodInvoker(delegate() { text = combobox.Text; })); 

Desde Invoke es sincrónica usted tiene la garantía de que text la variable contendrá el valor del texto cuadro combinado después de que regrese.

4

manera más corta es:

string text; 
this.Invoke(() => text = combobox.Text); 
+0

Esto no parece funcionar. Ver enlace: http://connect.microsoft.com/VisualStudio/feedback/details/395813/system-delegate-is-not-a-delegate-type – Bill

+0

@YongkeBillYu el enlace pide iniciar sesión. No veo por qué aunque no funcionaría, debería hacer lo mismo que la solución aceptada. –

+0

@Igor, aunque hay una advertencia: el compilador se queja del código a menos que [lo haya convertido en el tipo de acción] (http://stackoverflow.com/questions/411579/why-must-a-lambda-expression-be-cast -when-supplied-as-a-plain-delegate-parameter). Por favor, edita el código. –

Cuestiones relacionadas