Observable.Start documentation
RedGlow opened this issue · 6 comments
In "intro to RX", Part I, "Creating Observable Sequences", I read that:
Note the difference between Observable.Start and Observable.Return. The Start method invokes our callback only upon subscription, so it is an example of a 'lazy' operation. Conversely, Return requires us to supply the value up front. [...] Start doesn't begin the work until you subscribe to it. Moreover, it will re-execute the callback every time you subscribe to it. So it is more like a factory for a task-like entity.
But the documentation of Observable.Start, in its "remarks" section, states the contrary:
The action is called immediately, not during the subscription of the resulting sequence.
Multiple subscriptions to the resulting sequence can observe the action's outcome.
I performed a little test (using the code in the book as template):
using System.Reactive.Linq;
void StartAction()
{
var start = Observable.Start(() =>
{
Console.WriteLine($"{DateTime.Now} - Start working.");
for (var i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.Write(".");
}
Console.WriteLine($"\n{DateTime.Now} - Work completed.");
});
Console.WriteLine($"{DateTime.Now} - Waiting a little before subscribing...");
Thread.Sleep(2000);
Console.WriteLine($"{DateTime.Now} - Ok, subscribing!");
start.Subscribe(
_ => Console.WriteLine("SUB1: Unit published"),
() => Console.WriteLine("SUB1: Action completed"));
start.Subscribe(
_ => Console.WriteLine("SUB2: Unit published"),
() => Console.WriteLine("SUB2: Action completed"));
}
StartAction();
Thread.Sleep(2100);
And indeed the inline documentation seems right and the book wrong. In the output we can see that a) the computation starts before any subscription, and b) it does not re-execute the callback for every subscription.
13-Aug-24 9:37:15 AM - Start working.
13-Aug-24 9:37:15 AM - Waiting a little before subscribing...
..........
13-Aug-24 9:37:16 AM - Work completed.
13-Aug-24 9:37:17 AM - Ok, subscribing!
SUB1: Unit published
SUB1: Action completed
SUB2: Unit published
SUB2: Action completed
And indeed the inline documentation seems right and the book wrong.
I'm a bit confused about what exactly is it that you are asking based on the above. Isn't the documentation correct, then?
And indeed the inline documentation seems right and the book wrong.
I'm a bit confused about what exactly is it that you are asking based on the above. Isn't the documentation correct, then?
The inline documentation is, but the book is not. Maybe this is not the right place where to report errors in Intro to RX? Since its contents are in this repository, I thought it was...
Oh, my bad @RedGlow , I had no idea the source of the book was in the repo. You are probably correct in that this is the place to file the inconsistency.
My apologies. When we took over the book, I thought that the original text here was difficult to understand, so I tried to clarify it a bit. I guess I was right that it was hard to understand because I in fact completely misunderstood it, and my "clarified" version was wrong.
In my defence, the original was a best ambiguous, and, in my view, actively misleading. (It said "Start
lazily evaluates the value from a function". To me, "lazy" evaluation means deferred execution—you don't start the work until you know someone definitely wants the results. But it turns out that's not what the original author meant.) But I should have checked that my 'clarification' was correct.
You are correct that the inline doc comments are right, and the book is wrong.
As far as I can tell, the main interesting things about Start
are:
- work is run via a scheduler (and the default is
DefaultScheduler
, meaning it will invoke your method on a thread pool thread) - you get an
IObservable<T>
back immediately, even if the callback takes a long time to complete