2009-04-23 12 views
26

Utilizzando C# 2.0 e il delegato MethodInvoker, ho un'applicazione GUI che riceve alcuni eventi dal thread della GUI o da un thread di lavoro.Utilizzo di C# MethodInvoker.Invoke() per un'applicazione GUI ... è buono?

Io uso il seguente schema per la gestione dell'evento nella forma:

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

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

Utilizzando questo schema non duplicare il codice di interfaccia utente reale, ma quello che io non sono sicuro è se questo metodo è buono .

In particolare, la linea

method.Invoke() 

La usa un altro filo per invocare o esso tradurre alquanto ad una chiamata diretta al metodo sul thread GUI?

risposta

21

La chiamata method.Invoke() esegue il delegato sul thread di esecuzione corrente. L'utilizzo di BeginInvoke(method) assicura che il delegato venga chiamato nel thread della GUI.

Questo è il modo corretto di evitare la duplicazione del codice quando lo stesso metodo può essere chiamato sia dal thread della GUI che da altri thread.

+0

Grazie! Sono rimasto bloccato a usare method.Invoke e anche Invoke ((MethodInvoker). Tornando a BeginInvoke ha fatto il trucco –

0

Effettua la chiamata sullo stesso thread. Puoi controllare passando il codice. Non c'è niente di sbagliato in questo approccio.

2

Per WinForms, chiamando Control.Invoke(Delegate) si invia un messaggio alla pompa messaggi di thead. Il thread elabora quindi il messaggio e chiama il delegato. Una volta elaborato, Invoke interrompe il blocco e il thread chiamante riprende a eseguire il codice.

5

Ricordare che Control.InvokeRequired restituisce false se si è su thread in background E Control.IsHandleCreated è false. Salvaguarderei il codice con un Debug.Assert che controlla la creazione di handle non gestiti.

14

Personalmente mi piace questo metodo:

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

e quindi si può scrivere battute come questo:

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

Qui qualcosa sembra non funzionare. InvokeRequired funziona su un Control, lo stai solo mettendo fuori con niente. Che cosa significa? – Craig

+0

InvokeRequired è uguale a this.InvokeRequired. –