2009-12-10 11 views
12

Devo sapere se le chiamate Control.BeginInvoke e Control.Invoke verranno eseguite nell'ordine in cui sono chiamate.Più chiamate Control.BeginInvoke/Invoke verranno eseguite in ordine?

Ho il seguente scenario:

  1. thread UI è bloccato
  2. filo WCF chiama Control.BeginInvoke
  3. filo WCF chiama Control.Invoke (o eventualmente BeginInvoke nuovo)
  4. thread UI è sbloccato
  5. ??

L'ordine di esecuzione della fase 1-4 è garantito essere nell'ordine indicato (tecnicamente l'ordine non è garantito essere così, ma la domanda che ho è rilevante solo se l'ordine come mostrato).

La domanda che ho è se non v'è alcuna possibilità che la chiamata Invoke/BeginInvoke al punto 3 viene eseguito prima che la chiamata BeginInvoke al punto 2?

Inoltre, si prega di non commentare bloccare il thread UI.

risposta

10

Nel tuo caso, il passaggio 2 verrà sempre eseguito prima del passaggio 3. BeginInvoke sul thread dell'interfaccia utente verrà eseguito nell'ordine in cui è stato accodato.

Il thread dell'interfaccia utente è in effetti un messaggio pump, ha una coda di singolo messaggio con un solo thread che lo consuma, quindi è garantito che gli elementi di lavoro verranno eseguiti nell'ordine in cui sono stati messi in coda.

È con Delegate.BeginInvoke che l'ordine di esecuzione può essere non sequenziale.

+0

Quindi il commento che indica che le chiamate Invoke sincrone possono essere eseguite prima che la chiamata BeginInvoke asincrona non si applichi a Control.BeginInvoke, ma si applicherà a Delegate.BeginInvoke? Potete fornirmi un collegamento che spieghi questo? – cornergraf

+0

La tua affermazione è corretta. Ho aggiunto una breve spiegazione del messaggio UI pump nella risposta, stranamente non riesco a trovare una fonte ufficiale che lo dichiari. –

+0

Ok, grazie. Conosco il MessagePump in generale, ma ho pensato che le chiamate BeginInvoke/Invoke potessero potenzialmente avere un comportamento speciale per qualsiasi motivo e volevo essere sicuro – cornergraf

0

Non abbastanza informazioni per darvi una buona risposta. Il thread dell'interfaccia utente è bloccato, pertanto i passaggi 2 e 3 devono essere in esecuzione su un thread diverso. Se non c'è sincronizzazione tra i due, come possiamo conoscere gli ordini?

Thread 1  Thread 2      Thread 3   Thread 4 
Block UI  Calls BeginInvoke    
Unblock UI  Calls Invoke or BeginInvoke BeginInvoke runs BeginInvoke runs 

Hai un sacco un parallelismo in corso, ma da quello che hai descritto, non c'è modo possibile, potremmo dirvi cosa possibile si verificheranno ordinamenti, a corto di dicendo: "Qualsiasi cosa." Non possiamo nemmeno dirti che le chiamate a BeginInvoke non avverranno prima che il thread dell'interfaccia utente venga bloccato o dopo che il thread dell'interfaccia utente sia stato sbloccato.

+0

Ebbene, l'ordine dei passaggi 1-4 è garantita per accadere in questo ordine. La questione è solo se questo garantirà anche l'ordine di esecuzione della BeginInvoke/Invoke chiamate nei punti 3 e 4. sto aggiornando la questione per rendere questo più chiaro. – cornergraf

+0

Ahhh, la modifica che afferma che è 'Control.BeginInvoke' e' Control.Invoke' cambia molto. Sono contento che qualcuno sia stato in grado di coprirlo per te. :) –

+0

Sì, e mi sono appena reso conto di quanto si tende a dare certe informazioni per scontate quando si discute con gli altri. Cercherò di essere più preciso in futuro. Grazie per la tua risposta però. – cornergraf

3

chiamate BeginInvoke sono in coda sul filo di destinazione (in cui sono distaccati in ordine di arrivo).

chiamate sincrone sulla WCF filettatura (passaggio 3) possono essere eseguite prima chiamate asincrone (step 2) realizzati con questo thread.

+0

Ok, grazie mille. Ti capita di avere una fonte per quella dichiarazione? Ho cercato di trovare qualcosa di definito su google, ma senza successo finora. – cornergraf

0

Nessuna possibilità si può supporre che, ma se esiste una qualche forma di dipendenza tra le due chiamate sopra li hanno in attesa su un semaforo e solo eseguire il codice dipendente quando sono entrambi completati.

Se il motivo per cui si stanno effettuando le due chiamate contemporaneamente non è le prestazioni, probabilmente eseguirò la seconda chiamata nel callback del primo (è molto più facile eseguire il debug).

+0

effettivamente, i passaggi 3 e 4 potrebbero essere scambiati, ma se lo sono so che (ovviamente) il passaggio 2 sarà eseguire prima. Pertanto la mia domanda è pertinente solo nel caso in cui l'ordine di esecuzione sia esattamente come presentato, motivo per cui l'ho formulato in quel modo – cornergraf

Problemi correlati