2012-01-04 12 views
9

W starszych wersjach rozszerzeń reaktywnych zastosowano metodę rozszerzenia Uruchom i Wykonaj dla IEnumerable. Obaj wydają się robić dokładnie to samo i nie jestem pewien różnicy.Jaka jest różnica między Run a Do w Rx?

Pytam, ponieważ aktualizuję jakiś starszy kod, a Do został przeniesiony do Ix (który nie jest jeszcze w stabilnej wersji) i wygląda na to, że Run został zastąpiony przez ForEach.

+0

Jonathan, czy któraś z odpowiedzi ci pomogła? Jeśli tak, zaznacz jako odpowiedź. Dzięki! –

+1

Dla każdego, kto się zastanawia, odpowiednikiem "Run" w nowszych kompilacjach Rx jest metoda rozszerzenia Observable.Wait(). Ta metoda blokuje wykonanie, dopóki nie zostanie uzyskana ostateczna wartość lub wyjątek z obserwowalnego źródła. Wywołanie go powoduje wystąpienie subskrypcji. – thefellow3j

Odpowiedz

10

Do Określa, że ​​niektóre efekty uboczne będą miały miejsce po wykonaniu, i zwraca sekwencję z efektami ubocznymi.

Uruchom wylicza sekwencję i zwraca nieważny.

Pomyśl o tym tak: "oznacz" sekwencję z efektami ubocznymi. Te efekty uboczne będą miały miejsce tylko po wyliczeniu sekwencji. Czy zwraca nową sekwencję z efektami ubocznymi.

// 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, z drugiej strony, wylicza sekwencję: run(), albo ewentualnie przywiązuje skutków ubocznych, a następnie wylicza sekwencję: Run (działanie)

// 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

Myślę, że potrzebujesz "AsObservable()" po deklaracji tablicy (w przeciwnym razie działa na 'IEnumerable'). –

+0

Erm, jeśli się nie mylę, .Do i .Run są częścią interaktywnych rozszerzeń (IX), które działają na IEnumerable . –

+0

'Do' jest nadal na IEnumerable i IObservable. 'Run' * był * w obu okresach wydania WP7, ale teraz jest dostępny tylko jako część Ix. Powiedziawszy to, zdaję sobie teraz sprawę, że PO w istocie odnosi się do IEnumerable, a nie IObservable. Przeprosiny za zamieszanie. –

8

Można myśleć o Do jako "Peek", ponieważ wykonuje efekty uboczne dla każdej wartości/błędu/zakończenia, ale nie może zmienić ich wartości, ponieważ lambdas przekazał wszystkie puste objekty. Jest podobny do Subscribe, ale nie łamie monady ("łańcucha"), ponieważ zwraca IObservable<T>. Do jest często używany do logowania.

Run jest po prostu blokującą wersją Subscribe, co oznacza, że ​​wykonanie nie będzie kontynuowane po tej linii, dopóki nie zostanie wywołana funkcja OnComplete/OnError.

+0

Znakomita odpowiedź, dzięki temu spadła mi grosza. – Contango

6

Pomyśl o Wykonaj jako miernik Amp: przecinasz obwód (łańcuch operatorów zapytań) i podłączasz licznik (delegat akcji) do prądu (wartości przepływające przez operatorów zapytań). Dla każdego elektronu (wartości) przepływającego przez obwód (zapytanie), miernik (działanie) wykonuje pewną pracę. Zauważ, że obwód (zapytanie) jest wciąż wyłączony (leniwy). Dopóki nie podłączysz baterii (uruchom pętlę foreach), płynie prąd (wartości). Prostym sposobem włączenia obwodu (uruchomienie zapytania) jest użycie baterii (operator ForEach).

+0

Podoba mi się twoja analogia, ale ForEach to ładunek, a nie bateria:) Dopóki obwód się nie otworzy, nic się nie dzieje. –

3

Działa jak inni operatorzy LINQ, tacy jak Wybierz lub Gdzie - nic się nie dzieje, jeśli po prostu go użyjesz, musisz coś zrobić, aby foreach. Run/ForEach/Subscribe działa tak jak instrukcja foreach, wykonuje się natychmiast.

Jeśli nie masz 100% jasności, kiedy używać każdego z nich, unikaj Do i po prostu używaj ForEach/Run.

Powiązane problemy