2010-03-29 16 views

risposta

6

Il dispatcher può essere pensato come una coda che gli eventi vengono inviati; un dispatcher verrà eseguito sul thread dell'interfaccia utente ed eseguirà gli eventi per l'interfaccia utente. In Windows, i controlli dell'interfaccia utente possono essere modificati solo dal thread che li ha creati, quindi qualsiasi modifica all'interfaccia utente deve essere eseguita dal thread dell'interfaccia utente, quindi questo è uno dei motivi principali per cui le operazioni che modificano gli elementi della finestra devono essere inviate all'interfaccia utente dispatcher.

Un thread in background, a sua volta, è un thread diverso rispetto all'interfaccia utente. Quindi qualsiasi cosa venga eseguita su uno di questi thread non influirà o bloccherà l'interfaccia utente.

0

L'utilizzo del dispatcher per eseguire un'operazione a esecuzione prolungata lo causa ancora sul thread dell'interfaccia utente, solo con una priorità diversa rispetto all'operazione corrente. Il problema qui è che di solito, si desidera che l'operazione di lunga durata abbia la larghezza di banda che è possibile. Funzionando sotto il dispatcher, sei rallentato dall'interfaccia utente.

Il punto del dispatcher è di fornire un'ancora a un thread in background all'interfaccia utente in modo che sia possibile fornire ad esempio un aggiornamento all'interfaccia utente sullo stato di avanzamento dell'operazione.

Se si desidera eseguire un'operazione in background e rinviare l'esecuzione all'interfaccia utente, utilizzare un backgroundworker o la nuova libreria di attività. Utilizzare il dispatcher per eseguire il marshalling degli aggiornamenti sull'interfaccia utente.

2

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.

0

Le operazioni invocate da entrambi i metodi verranno posizionate nella coda eventi da eseguire sul thread dell'interfaccia utente. Invoke si verifica in modo sincrono e blocca fino al completamento dell'operazione, BeginInvoke si verificherà in modo asincrono consentendo al metodo di chiamata di continuare l'esecuzione.

Problemi correlati