Il concetto di BeginInvoke e Invoke può essere pensato come segue.
- BeginInvoke significa: ". Fate questo e tornare prima che sia completata io o non mi interessa il valore di ritorno o puoi chiamarmi di nuovo a questo indirizzo ad un certo punto in futuro"
- Invoke significa: "Fai questo e mi siederò qui e aspetto che si completi".
Ora, il modo in cui questo si riferisce agli spedizionieri e ai thread in background è un'altra cosa. Come dice Justin, il Dispatcher elabora una coda di cose da fare ogni volta che il thread dell'interfaccia utente diventa inattivo. Un thread in background che chiama BeginInvoke sul dispatcher verrà restituito immediatamente anche se il dispatcher potrebbe non aver ottenuto l'elaborazione. Se invece fosse stato usato Invoke, il thread in background si bloccava fino a quando il thread dell'interfaccia utente non ha completato l'elaborazione. Si noti che in Silverlight non è presente Invoke sul Dispatcher e nella maggior parte dei casi probabilmente non si desidera bloccare il thread in background mentre il thread dell'interfaccia utente viene elaborato.
Al contrario, Delegate.BeginInvoke utilizza i thread di lavoro nel pool di thread. Quando si utilizza il thread dell'interfaccia utente (o qualsiasi thread) è possibile chiamare BeginInvoke e Invoke su un delegato. BeginInvoke utilizzerà un thread di lavoro per chiamare il delegato utilizzando la stessa semantica descritta in precedenza. Invoke, tuttavia, non userebbe un thread diverso. Dovrebbe semplicemente richiamare il delegato in modo sincrono nel contesto del thread chiamante e restituirlo una volta completato.
Prestare attenzione quando si utilizza l'esecuzione sincrona su thread anche se questo spesso si traduce in deadlock se non stai molto attento.