Windows Phone From Scratch #26
I’m increasingly convinced that Reactive Programming is going to be critical for Silverlight and Windows Phone developers. Reactive Programming is not new, and the Rx toolkit has been out for a while, but this is not a heavily covered topic, and the more I look the more I think it should must be.
In short, Reactive Programming is a way to take aspects of your code that are currently imperative and turn them into something much more event-driven. In fact, Reactive Programming is sometimes referred to as LINQ Over Events.
This is tremendously helpful with asynchronous programming, but also with managing routine programming as well.
Let me start by acknowledging some of the foundation videos that are already available for Reactive Programming, including
- Inside the .NET Reactive Framework (Rx)
- Inside .NET Rx and IObservable/IObserver in the BCL (VS 2010)
- Reactive Framework (Rx) Underneath the Hood
To get our feet wet, let’s create a very first program with the Reactive Programming Extensions (you want Rx for Silverlight 4). What I’m about to demonstrate is not original; the idea has been used in other folk’s examples and I’m grateful to them all.
Enumeration Vs. Observation
Much of Reactive Programming turns on the idea of an Observable Collection vs. a simple enumerable collection. For example, to extract data from a collection and add it to a list box you would traditionally iterate through the list box, extracting each objectg in turn and add it to the list box.
In Reactive Programming you are informed about each object in turn (think of this as push as opposed to pull!) and you may react to each notification however you like, for example you might add the pushed object to a list box.
An example makes this much clearer. Create a new Windows Phone project and on the first page divide the Content panel into two columns. Place a list box in each of the two columns, naming the first lbEnumerable and the second lbObservable.
We need some data so let’s initialize a List<string> with the names of the first five presidents:
readonly List<string> names = new List<string> { "George Washington", "John Adams", "Thomas Jefferson", "James Madison", "James Monroe", "John Quincy Adams" };
This member variable will be the source for populating both list boxes. We’ll do all of the work in a method called PopulateCollection() that we’ll call from the constructor.
In the first part of PopulateCollection() we’ll take the traditional approach and iterate through each member of the collection, adding each president’s name to the list box,
private void PopulateCollection() { foreach ( string pName in names ) { lbEnumerable.Items.Add( pName ); }
That works great, but it is possible that you won’t have the entire collection at your fingertips; rather you may be provided with each individual name one by one based on events whose timing you may not control. Reactive programming solves that problem for you. You can simulate this by converting the list<string> to an observable collection (that is, a collection that implements IObservable).
To do this, first ensure that you have added System.Core.Ex, Microsoft.Phone.Reactive and System.Observable to your references. Then use the ToObservable() extension method on your List of names to create an instance of an IObservable collection,
IObservable<string> observable = names.ToObservable();
The subscribe method of an observable collection is overloaded. The first parameter you can pass in is of type Action<T> which subscribes a value handler to an observable sequence. Again, the code makes this clearer,
observable.Subscribe<string> ( pName => { lbObservable.Items.Add( pName ); } );
The highlighted code is the body of the Action<T> which in this case is a Lambda expression indicating that given a string pName the body of the “method” adds that name to the appropriate list box.
I will return to Rx frequently in coming days and we’ll tackle some more complex examples as we go.
The key question that has to be answered, and to which I honestly don’t yet know the answer, is this: Is Reactive Programming going to become central to Windows Phone Programming, or will it remain an esoteric and peripheral approach?
For context, here is the complete program:
using System; using System.Collections.Generic; using Microsoft.Phone.Controls; using Microsoft.Phone.Reactive; namespace Rx1 { public partial class MainPage : PhoneApplicationPage { readonly List<string> names = new List<string> { "George Washington", "John Adams", "Thomas Jefferson", "James Madison", "James Monroe", "John Quincy Adams" }; public MainPage() { InitializeComponent(); PopulateCollection(); } private void PopulateCollection() { foreach ( string pName in names ) { lbEnumerable.Items.Add( pName ); } IObservable<string> observable = names.ToObservable(); observable.Subscribe<string> ( pName => { lbObservable.Items.Add( pName ); } ); } } }
Special Thanks to Pencho Popadyn whose demonstration program was the basis for my example.
Hello, I would like to subscribe for this blog to take latest updates, therefore where
can i do it please assist.
my page blog account access (http://www.ask.com/)
Dim taskList As ObservableCollection(Of v2_Customer) = New ObservableCollection(Of v2_Customer)
” Dim custID As Guid = (CType(V2_CustomerDataGrid.SelectedItem, _
” v2_Customer)).Cust_UUID
” Generate some task data and add it to the task list.
For index = 0 To taskList.Count – 1
taskList.Add(New v2_Customer() With _
{.Cust_UUID = custID, .Billing_Zip = .Billing_Zip
})
Next
Dim taskListView As New PagedCollectionView(taskList)
Me.CustomerDataForm1.ItemsSource = taskListView
@ Dennis. You are precisely correct. This is simply an implementation of the Observer pattern as per the Gang of Four Design Patterns book sitting on my desk written in 1994.
It’s not revolutionary, and we’ve been using the Observer pattern for years successfully. However it is fantastic that MS have standardised it into the framework and thought about the follow on issues such as thread safety and scheduling when using the pattern across multiple threads.
Thanky Thanky for all this good infortaimon!
@Dennis
…and others discussing yield.
couldn’t you use a lamda expression or the new stellar async programming features of 4.0? yeild is ineed part of 4.0 now.
@Anony-mouse
Flash has never been unnamed here. And Silverlight also has events; what I’m discussing here is a new model that does not replace events but which provides a uniquely clean way to deal with asynchronicity
Flash has event-based programming built-in since Actionscript 2. With AS3, the EventListener with callbacks makes for very clean, understandable code.
Or is Flash still “That-Which-Shall-Not-Be-Named?”
Interesting blog post. Interesting also that you said I “should stop what I am doing and learn about reactive programming” and then concluded it might not be that popular or useful.
Kind of mixed messages.
@Dennis
I am a member of everyone and react by observing that I do not know the observable pattern. It is new to me.
I took the time to learn about Rx a few months ago. For application that perform asynchronous application Rx makes life much easier. I wrote a few mashups that were implemented as one-line Rx pipelines:
http://www.scottlogic.co.uk/blog/colin/exploring-reactive-extensions-rx-through-twitter-and-bing-maps-mashups/
A very powerful tool indeed!
@James Manning
Your picks are not nits; that is, your points are well taken and I appreciate your taking the time to spell all that out.
Could you not do the exact same thing with function pointers/functors?
To be honest I don’t see the “newness”. Looks like a good old-fashioned observer pattern. There’s probably some neat implementation details, but shirley everyone knows the observable pattern.
Unbelievable how well-written and ifnoratimve this was.
I’ve played around with Rx a bit. This example is a bit too simplistic in the sense that it doesn’t show why Rx is better. While the above shows you how to set things up, using the usual IEnumerable pattern is cleaner.
But suppose the source is async rather than a static list/listbox. Say you’ve sent a few web requests to get lists of names which you are then going to put into a single list box. Some servers are fast/some slow, and multiple servers may be responding at the same time. Now Rx starts to shine – you can just merge those streams of strings into a single observable, and then subscribe the inserter in that subscribe.
There are some downsides. The C# compiler knows the IEnumerable pattern – you can use the yield return keyword in a method, for example. No such support exists for Observables (don’t know how you’d do it anyway).
The other thing that constantly trips me up if my pipe-line gets at all complex: as soon as a subscription is made the events start to flow, so if you then subscribe to the end of a pipe that is already running you’ll miss anything that has gone before. You have to think about how this works differently since it is a push model, not a ask model! The workaround is that observable re-starts the sequence everytime you subscribe (which is then bad if you want a single time sequence, etc. etc.). There are ways around all of this, but for me I had to think about these issues – ones I never had to think about with IEnumerable.
The other thing that drove me up a wall with earlier implementations of Rx was the thread context switching wasn’t always sensible. I think that has been fixed, but I’ve not had a project that requires something like Rx since then.
As far as asking if IEnumerable is better. Look at the demo that does mouse movements – one of the original 10 minute starter videos. I’ve not tried, but I wonder how much work you’d need to get the same thing with IEnumerable.
At the very least it gets you thinking about something that is absolutely crucial for WP7 – get *everything* you can off the main thread. The performance of some apps (like the facebook app, the flickr manager app, etc.) could do with a healther dose of this sort fo thinking.
+1 @James Manning Great Explanation. Pragmatic.
@Stimul8d – it’s just an unfortunate naming similarity – ObservableCollection predates (obviously, given its history in WPF which was in .NET 3.0) IObservable/IObserver (new in .NET 4). ObservableCollection uses the existing .NET events (exposed via the INotify* interfaces in its case) for communicating changes. The IObservable/Subscribe approach is an alternative method of communicating (‘pushing’) such notifications with no .NET events being used (Indeed, IIRC Erik Meijer even said that the events as we know them today likely wouldn’t exist if IObservable had been around in the 1.0 days).
@Jesse – it’s likely nit-picky, but I don’t like this particular phrasing: “The subscribe method of an observable collection is overloaded. The first parameter you can pass in is of type Action” – Certainly one big issue is using the phrase ‘observable collection’ which can/will/does lead to confusion with ObservableCollection. Another reason is that the IObservable interface (like what you get back from the ToObservable call) only supports *one* possible parameter – unsurprisingly, that of IObserver.
http://msdn.microsoft.com/en-us/library/dd782981(v=VS.92).aspx
Now, much like with IEnumerable and IQueryable, there are lots of extension methods being offered (in their case, by Enumerable and Queryable – in this case, by the unsurprisingly named Observable) to make things far easier to work with, but IMHO it’s worth calling out the difference so people understand what’s ‘core’ to the interfaces (IObservable+IObserver) vs. what’s layered on top via extension methods. I think this came somewhat naturally in the linq-to-objects view of things since IEnumerable had been around so long.
Again, admittedly nit-picky, but since we don’t (yet?) have such in-language compiler keywords/transformations like ‘yield return’ and the like, if/when people are considering implementing IObservable on their own, it’s good to know they only need to support accepting an IObserver and returning back a disposable. 🙂
Atlast got some info. Rx is just like the TPL DataFlow(which is not available for .net 3.5) which can be used to perform Non-Blocking Async IO operations. Performance wise I didn’t find any advantage of IObservable over data bound ObservableCollection. As Jessie mentioned. This could be future of W7P. The main reason should Non-Blocking IO which is essential for any mobile computing device. Thanks all… Happy weekend 🙂
The real beauty of this is when you think about things like how it can replace the standard event subscription model.
Same question I guess, is that I’m struggling to see the advantage here.
Fine it seems a quicker and more reactive way to add items to a list during load. However tried adding more items to the original list and it didn’t update (which I was expecting through the subscription, unless I read that wrong)
And there doesn’t seem a way to add items to an iObservable list, it is only a query object.
SO if I load a set of items from the web, fine this seems a cleaner way to then present it, however if I am continually updating te list or adding more items, then an ObservableCollection seems better.
IList is always supporting the IEnumerable ? What is the difference
“
Good point!
What is the difference between IObservable and ObservableCollection data bound with list box?
Great Article, thanks for posting