2009-04-23 14 views
26

Utilizando C# 2.0 y el delegado de MethodInvoker, tengo una aplicación de GUI que recibe algún evento del subproceso GUI o de un subproceso de trabajo.Utilizando C# MethodInvoker.Invoke() para una aplicación GUI ... es tan bueno?

uso el siguiente patrón para controlar el evento en la forma:

private void SomeEventHandler(object sender, EventArgs e) 
{ 
    MethodInvoker method = delegate 
     { 
      uiSomeTextBox.Text = "some text"; 
     }; 

    if (InvokeRequired) 
     BeginInvoke(method); 
    else 
     method.Invoke(); 
} 

Mediante el uso de este patrón no duplicar el código de interfaz de usuario real, pero lo que no estoy seguro es si este método es bueno .

En particular, la línea

method.Invoke() 

¿utiliza otro hilo para invocar o se traduce tanto a una llamada directa al método en el subproceso de interfaz gráfica de usuario?

Respuesta

21

La llamada method.Invoke() ejecuta el delegado en el hilo de ejecución actual. El uso del BeginInvoke(method) asegura que se llame al delegado en el hilo de la GUI.

Esta es la forma correcta de evitar la duplicación de código cuando se puede llamar al mismo método tanto desde el hilo de la GUI como desde otros subprocesos.

+0

Gracias! Me quedé atrapado en el método. Invoke e incluso Invoke ((MethodInvoker). Volver a BeginInvoke hizo el truco. –

0

Realiza la llamada en el mismo hilo. Puede verificarlo al recorrer el código. No hay nada malo con ese enfoque.

2

Para WinForms, al llamar al Control.Invoke(Delegate) se envía un mensaje a la bomba de mensajes de theUI's thead. El hilo luego procesa el mensaje y llama al delegado. Una vez que se ha procesado, Invoke deja de bloquearse y el hilo de llamada reanuda la ejecución del código.

5

Tenga en cuenta que Control.InvokeRequired devuelve falso si está en la secuencia de fondo Y Control.IsHandleCreated es falso. Protegería el código con una depuración. Afirme que comprueba la creación de manejadores no gestionados.

14

Personalmente me gusta este método:

private void ExecuteSecure(Action a) 
{ 
    if (InvokeRequired) 
     BeginInvoke(a); 
    else 
     a(); 
} 

y luego se puede escribir una sola línea como esta:

ExecuteSecure(() => this.Enabled = true); 
+0

Algo no se ve aquí. InvokeRequired opera en un Control, lo estás sacando con nada. ¿Qué significa? – Craig

+0

InvokeRequired es el mismo que this.InvokeRequired. –

Cuestiones relacionadas