2009-05-25 18 views
6

Ho creato un Testbox per informazioni sul threading nelle applicazioni del modulo Windows. Silverlight e Java forniscono il Dispatcher, il che aiuta molto nell'aggiornare gli elementi della GUI .Problema con il delegato Sintassi in C#

esempi di codice: Dichiarazione classe Delegate

public delegate void d_SingleString(string newText); 

Crea Discussione

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

Funzione Discussione Aggiornamenti

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

Delega TextBox

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

C'è un modo per dichiarare la dichiarazione del delta nel metodo BeginInvoke ?!

qualcosa come

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

Molte grazie, rAyt

risposta

9

In molti casi, l'approccio più semplice consiste nell'utilizzare una "variabile acquisita" per passare lo stato tra i thread; questo significa che è possibile mantenere la logica localizzata:

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

Quanto sopra è particolarmente utile se ci aspettiamo tanto da essere chiamato sul thread di lavoro (così poco punto il controllo InvokeRequired) - notare che questo è sicuro sia dal Interfaccia utente o thread di lavoro e ci consente di passare il massimo o il minimo tra i thread.

+0

Ama la tua Eloboration Marc. Ho appena imparato molto di più che leggere MSDN per 10 minuti :) –

+0

Le meraviglie degli appartamenti single thread ... – Spence

+0

Soluzione molto elegante; questa dovrebbe essere la risposta accettata per questa domanda. –

4

Per semplici delegati come questo è possibile utilizzare il Action<T> delegato (link to msdn) dal quadro.

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

In questo modo non è necessario per mantenere le proprie dichiarazioni dei delegati.

+2

E Func se ha bisogno di valori di ritorno ... – tanascius

+0

Grande! Grazie Fredrik. –

+0

tanascius, puoi specificare il tuo commento? Grazie! –