2009-05-25 12 views
6

Creé un Testbox para aprender algo sobre el enhebrado en las aplicaciones de formularios de Windows. Silverlight y Java proporcionan el Dispatcher, lo que realmente ayuda al actualizar Elementos de GUI.Problema con la sintaxis de delegado en C#

Ejemplos de código: Declaración clase Delegate

public delegate void d_SingleString(string newText); 

Crear secuencia

 _thread_active = true; 
     Thread myThread = new Thread(delegate() { BackGroundThread(); }); 
     myThread.Start(); 

Tema función actualiza

private void BackGroundThread() 
    { 
     while (_thread_active) 
     { 
      MyCounter++; 
      UpdateTestBox(MyCounter.ToString()); 
      Thread.Sleep(1000); 
     } 
    } 

Delegar TextBox

public void UpdateTestBox(string newText) 
    { 
     if (InvokeRequired) 
     { 
      BeginInvoke(new d_SingleString(UpdateTestBox), new object[] { newText }); 
      return; 
     } 
     tb_output.Text = newText; 
    } 

¿Hay alguna manera de declarar la Declaración del Delate en el método BeginInvoke?

algo así como

BeginInvoke(*DELEGATE DECLARATION HERE*, new object[] { newText }); 

Muchas gracias, RAYT

Respuesta

9

En muchos casos como este, el enfoque más simple es usar una "variable capturada" para pasar el estado entre los hilos; esto significa que puede mantener la lógica localizado:

public void UpdateTestBox(string newText) 
{ 
    BeginInvoke((MethodInvoker) delegate { 
     tb_output.Text = newText; 
    });   
} 

Lo anterior es particularmente útil si esperamos que sea llamado en el subproceso de trabajo (tan poco punto de comprobación InvokeRequired) - en cuenta que esto es seguro, ya sea del UI o subproceso de trabajo, y nos permite pasar tanto o tan poco estado entre los subprocesos.

+0

Love your eloboration Marc. Acabo de aprender mucho más que leer MSDN por 10 minutos :) –

+0

Las maravillas de apartamentos de una sola rosca ... – Spence

+0

Solución muy elegante; esa debería ser realmente la respuesta aceptada para esta pregunta. –

4

Para los delegados simples como esto puede utilizar el Action<T> delegado (link to msdn) del marco.

public void UpdateTestBox(string newText) 
{ 
    if (InvokeRequired) 
    { 
     BeginInvoke(new Action<string>(UpdateTestBox), new object[] { newText }); 
     return; 
    } 
    tb_output.Text = newText; 
} 

De esta manera no necesita mantener sus propias declaraciones de delegado.

+2

Y Func si necesita valores devueltos ... – tanascius

+0

¡Genial! Gracias Fredrik. –

+0

tanascius, ¿puedes especificar tu comentario? ¡Gracias! –