I am new to Rx and was going through some samples and came across the below:
Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
h => new RoutedEventHandler(h),
h => Loaded += h,
h => Loaded -= h)
.Select(_ => true)
.StartWith(IsLoaded)
.Where(l => l)
.Take(1)
.Subscribe(_ => Console.WriteLine("loaded");
I am trying to deconstruct this statement to figure out what it is doing but it is not 100% clear to me.
I understand how FromEventPattern is turning the Loaded event into an observable sequence. Now, Select is going to trigger when IsLoaded is true (that is what I am assuming). Is Select just getting its info from the RoutedEventArgs?
Now, I am not sure why StartsWith is there. StartsWith will prepend a sequence of values to an observable sequence. So is it just adding the value of IsLoaded to the beginning of the list? Wouldn’t it already be there after Select happens?
.Where is not applying any sort of filter so .Take will just take the first value of the sequence (which in this case is not used any further). Then it Subscribes and the Console is written to only when the control is loaded.
Is this analysis mostly correct?
Also, any tips on debugging such things (meaning, what the sequence looks like during different stages of the chain)? I can get info just by attaching the debugger but I was wondering if there are any other tricks/tips that might be commonly used.
Most of the Observable operators work the same way the Enumerable operators of the same name. If you have experience using those, it will be useful here.
So to work through this, let’s use an array of integer instead of the observable for a moment.
This changes the expression to
If you made an array at each stage in the expression you would get:
With IEnumerables, doing this sort of thing doesn’t make much sense because you will always get one value that is true (unless the source array is empty and IsLoaded is false).
The use of this with an IObservable is to make something that will produce one signal when the object is loaded.
StartWithis provides the signal if the object is already loaded at the time of subscription.IsLoadedwill be false, theWherewill filter it out, and when the event fires, it will trigger a notification.Selectwill ignore the actual data produced by the event and simply pass a true, which will proceed through theWherefilter.Takeis used to only trigger the notification once, regardless of it it comes from theStartWith, because the object was already loaded, or the event (viaSelect), when loading completes.