2012-01-04 11 views
9

Le versioni precedenti di Reactive Extensions disponevano di un metodo di estensione Run e Do per IEnumerable. Entrambi sembrano fare la stessa identica cosa, e non sono sicuro della differenza.Qual è la differenza tra Esegui e Esegui in Rx?

Sto chiedendo perché sto aggiornando un vecchio codice e Do è stato spostato su Ix (che non è ancora in una versione stabile), e sembra che Run sia stato sostituito da ForEach.

+0

Jonathan, qualcuna delle risposte ti ha aiutato? In tal caso, contrassegnare come risposta. Grazie! –

+1

Chiunque si chieda, l'equivalente di "Esegui" nei nuovi build Rx è il metodo di estensione Observable.Wait(). Questo metodo blocca l'esecuzione finché il valore finale o un'eccezione non viene ricevuta dalla sorgente osservabile. Invocandolo si verifica un abbonamento. – thefellow3j

risposta

10

Do specifica che alcuni effetti collaterali avranno luogo quando vengono eseguiti e restituisce la sequenza con effetti collaterali.

Esegui enumera la sequenza e restituisce void.

Pensate in questo modo: fate "tag" la sequenza con effetti collaterali. Questi effetti collaterali si avranno solo quando la sequenza è enumerata. Do restituisce la nuova sequenza con effetti collaterali.

// Example of .Do 
var elements = new[] { 1, 2, 3 }; 
var elementsWithSideEffects = elements.Do(e => MessageBox.Show(e)); // No Message Boxes shown yet! 
elementsWithSideEffects.Run(); // 3 message boxes shown 

Run, d'altra parte, enumera la sequenza: Run(), o, in alternativa attribuisce effetti collaterali, quindi enumera la sequenza: Run (azione)

// Example of .Run with its own side effects: 
var elements = new[] { 1, 2, 3 }; 
elements.Run(e => MessageBox.Show(e)); // 3 Message Boxes shown. 
+2

Penso che sia necessario un 'AsObservable()' dopo le dichiarazioni dell'array (altrimenti è in esecuzione su 'IEnumerable'). –

+0

Ehm, se non erro, .Do e. Run sono parte di Interactive Extensions (IX), che opera su IEnumerable . –

+0

'Do' è ancora su IEnumerable e IObservable. 'Run' * era * su entrambi i tempi di rilascio del WP7, ma ora è disponibile solo come parte di Ix. Detto questo, ora mi rendo conto che il PO si riferiva effettivamente a IEnumerable e non a IObservable. Scuse per la confusione. –

8

si può pensare Do come "Peek" poiché esegue gli effetti collaterali per ogni valore/errore/completamento ma non può modificare i loro valori poiché lambdas ha superato tutti i valori restituiti. È simile a Subscribe, ma non interrompe la monade ("catena") in quanto restituisce IObservable<T>. Do viene spesso utilizzato per la registrazione.

Run è fondamentalmente una versione di blocco di Subscribe, il che significa che l'esecuzione non continua oltre quella riga finché non è stato chiamato OnComplete/OnError.

+0

Risposta brillante, questo ha fatto cadere il penny per me. – Contango

6

Pensa a come un misuratore di amplificazione: interrompi il circuito (la catena di operatori di query) e collegano un misuratore (un delegato di azione) per la corrente (i valori che fluiscono attraverso gli operatori di query). Per ogni elettrone (valore) che fluisce attraverso il circuito (query), il misuratore (azione) esegue un po 'di lavoro. Notare che il circuito (query) è ancora spento (pigro). Non è fino a quando non si collega la batteria (eseguire un ciclo foreach) che corrente (valori) stanno scorrendo. Un modo semplice di accendere il circuito (eseguire la query) consiste nell'utilizzare una batteria (l'operatore ForEach).

+0

Mi piace la tua analogia, ma ForEach è un carico, non una batteria:) Fino a quando il circuito è aperto, non succede nulla. –

3

Si comporta come gli altri operatori LINQ come Seleziona o Dove - non succede nulla se lo usi, devi fare foreach perché qualcosa accada. Esegui/ForEach/Subscribe funziona come l'istruzione foreach, viene eseguita immediatamente.

Se non si è al 100% chiaro quando utilizzare ognuno di essi, evitate Do e utilizzate solo ForEach/Run.

Problemi correlati