A volte uso (in Load)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
o
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(cambia "this" nella variabile del modulo se gestisci l'evento su un'istanza diversa da "this").
Questo inserisce l'invoke nel ciclo di windows-forms, quindi viene elaborato quando il modulo sta elaborando la coda dei messaggi.
[aggiornato su richiesta]
I metodi Control.Invoke / Control.BeginInvoke sono destinati all'uso con il threading e sono un meccanismo per inviare il lavoro al thread dell'interfaccia utente. Normalmente viene utilizzato dai thread di lavoro, ecc. Control.Invoke esegue una chiamata sincrona, mentre Control.BeginInvoke esegue una chiamata asincrona.
Normalmente, questi sarebbero usati come:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
Lo fa inserendo un messaggio nella coda dei messaggi di Windows; il thread dell'interfaccia utente (a un certo punto) rimuove il messaggio dalla coda, elabora il delegato e segnala al lavoratore che è stato completato ... finora tutto bene ;-p
OK; quindi cosa succede se usiamo Control.Invoke / Control.BeginInvoke sul thread dell'interfaccia utente? Affronta ... se chiami Control.Invoke, è abbastanza sensato sapere che il blocco sulla coda dei messaggi causerebbe un deadlock immediato, quindi se sei già sul thread dell'interfaccia utente esegue semplicemente il codice immediatamente ... in modo che non ci aiuta ...
Ma Control.BeginInvoke funziona in modo diverso: spinge sempre il lavoro in coda, anche se siamo già nel thread dell'interfaccia utente. Questo rende un modo davvero semplice per dire "in un momento", ma senza l'inconveniente dei timer ecc (che dovrebbero comunque fare la stessa cosa!).