В чем разница между Run и Do в Rx? - PullRequest
9 голосов
/ 04 января 2012

В более ранних версиях Reactive Extensions для IEnumerable использовался метод расширения Run и Do. Кажется, они оба делают одно и то же, и я не уверен в разнице.

Я спрашиваю, потому что обновляю какой-то старый код, и Do был перемещен в Ix (который еще не выпущен в стабильном выпуске), и похоже, что Run был заменен ForEach.

Ответы [ 4 ]

11 голосов
/ 04 января 2012

Do указывает, что некоторый побочный эффект будет иметь место при выполнении, и возвращает последовательность с побочными эффектами.

Run перечисляет последовательность и возвращает void.

Думайте об этом так:Делайте «теги» последовательности с побочными эффектами.Эти побочные эффекты будут иметь место только при перечислении последовательности.Do возвращает новую последовательность с побочными эффектами.

// 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, с другой стороны, перечисляет последовательность: Run () или, при желании, присоединяет побочные эффекты, затем перечисляет последовательность: Run (действие)

// Example of .Run with its own side effects:
var elements = new[] { 1, 2, 3 };
elements.Run(e => MessageBox.Show(e)); // 3 Message Boxes shown.
8 голосов
/ 05 января 2012

Вы можете думать о Do как о «взгляде», поскольку он выполняет побочные эффекты для каждого значения / ошибки / завершения, но не может изменять их значения, поскольку лямбда-выражения прошли все возвращаемые пустые значения.Это похоже на Subscribe, но оно не разрывает монаду («цепочку»), так как возвращает IObservable<T>.Do часто используется для ведения журнала.

Run - это, по сути, блокирующая версия Subscribe, то есть выполнение не продолжается после этой строки, пока не будет вызван OnComplete / OnError.

6 голосов
/ 05 января 2012

Думайте о Do как об амперметре: вы разрываете цепь (цепочку операторов запросов) и подключаете счетчик (делегат действия) для тока (значения, проходящие через операторы запроса).Для каждого электрона (значения), проходящего через цепь (запрос), измеритель (действие) выполняет некоторую работу.Обратите внимание, что схема (запрос) по-прежнему выключена (ленивый).Только когда вы подключите аккумулятор (запустите цикл foreach), ток (значения) будет течь.Простой способ включить схему (запустить запрос) - использовать аккумулятор (оператор ForEach).

3 голосов
/ 05 января 2012

Действует как другие операторы LINQ, такие как Select или Where - ничего не произойдет, если вы просто используете его, вы должны foreach, чтобы что-то произошло.Run / ForEach / Subscribe действует как оператор foreach, он выполняется немедленно.

Если вы не уверены на 100%, когда использовать каждый из них, избегайте Do и просто используйте ForEach / Run.

...