The older versions of Reactive Extensions had both a Run and Do extension method for IEnumerable. They both seems to be doing the exact same thing, and I'm unsure of the difference.
I'm asking because I'm upgrading some older code, and Do has been moved to Ix(which isn't at a stable release yet), and it looks like Run has been replaced by ForEach.
Do specifies that some side effect will take place when executed, and returns the sequence with side effects.
Run enumerates the sequence, and returns void.
Think of it like this: Do "tags" the sequence with side effects. Those side effects will take place only when the sequence is enumerated. Do returns the new sequence with side-effects.
// 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, on the other hand, enumerates the sequence: Run(), or optionally attaches side effects, then enumerates the sequence: Run(action)
// Example of .Run with its own side effects:
var elements = new[] { 1, 2, 3 };
elements.Run(e => MessageBox.Show(e)); // 3 Message Boxes shown.
You can think of Do
as "Peek" since it executes side effects for each value/error/completion but cannot change their values since the lambdas passed all return void. It's similar to Subscribe
, but it doesn't break the monad ("chain") as it returns IObservable<T>
. Do
is often used for logging.
Run
is basically a blocking version of Subscribe
, meaning execution does not continue past that line until OnComplete/OnError has been called.
Think of Do as an Amp meter: you cut open the circuit (the chain of query operators) and wire up a meter (an action delegate) for the current (the values flowing through the query operators). For every electron (value) flowing through the circuit (query), the meter (action) performs some work. Notice the circuit (query) is still powered off (lazy). It's not until you plug in the battery (run a foreach loop) that current (values) are flowing. A simple way of turning on the circuit (run the query) is to use a battery (the ForEach operator).
Do acts like other LINQ operators like Select or Where - nothing happens if you just use it, you've got to foreach
for something to happen. Run/ForEach/Subscribe acts like the foreach
statement, it executes immediately.
If you're not 100% clear on when to use each one, avoid Do and just use ForEach/Run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With