Whether reacting to user-input or handling responses from web services, Silverlight applications are typically asynchronous in nature. The framework provides UI controls that fire events in response to user interactions. There are also classes like the DispatcherTimer and WebControl that perform some background work, firing events which are helpfully marshalled back onto the UI thread. However, Silverlight and the other .NET UI frameworks lack a way of orchestrating these asynchronous activities.

In this article, I will look at how the Reactive Extensions (Rx) library provides a common interface for asynchronous events and actions giving a consistent way to composite, orchestrate and marshal events between threads (and also have some fun creating a few cool mashups along the way!)

This article builds a couple of Rx powered Silverlight applications step by step, the final one being a Twitter / Bing Maps mashup that shows the location of snowfall in the UK based on users Tweets to the #uksnow hashtag.

The Linq version of our code to find the odd numbers produces the same result as the ‘manual’ approach, however, the way in which it is executed is quite different. The Linq query is constructed by applying the Where operator to our source data, however, at this point the condition is not evaluated on the source. If we expand the foreach loop, we can see that it uses an enumerator which is obtained from the result for our query.

Each call to the MoveNext method on the enumerator is ‘pulling’ data from our query, with the condition being evaluated on each element of the source as and when it is needed. This ‘pull’ model results in deferred execution (or lazy evaluation depending on your preferred terminology) of the query. In the above example, our IEnumerable source is a list of fixed size, although in more general terms it is simply a source of data from which we can pull items and does not have to have a fixed size.

Again, the output of the above code is exactly the same as the Linq equivalent. The ToObservable extension method returns an IObservable which is the Rx analogue of the IEnumerable interface in that it is a source of items. The Rx library defines many Linq-like extension methods for manipulating IObservable sources of data, if you explore the above code via Intellisense, you will find many familiar methods (Where, Select, Max, SelectMany ...).

The Rx library also defines the IObserver interface which is an analogue of the IEnumerator interface that is ‘hidden’ by the foreach syntax. The IObservable has a Subscribe method where you provide an IObserver. The observable source will invoke the OnNext method on the IObservable as items are pushed. Often IObserver is hidden via the Subscribe extension methods on IObservable which creates an IObserver instance for you, with your delegate method invoked when OnNext is invoked by the observable source.

So, we have seen the similarities between Linq and Rx, but what are the differences?

The key difference is in what ‘drives’ the execution. With Linq, we iterate over the result of the query, ‘pulling’ the items from the IEnumerable source. With Rx, as soon as the subscription to our IObservable source is made, the items are ‘pushed’ to our subscriber.

The above trivial example was selected in order to highlight the similarities between Rx and Linq, and the net result is exactly the same. Where Rx comes into its own is the extensions methods it provides to create IObservable sources from events or asynchronous web service calls, allowing the developer to apply familiar Linq style operations. We’ll look at a slightly more interesting example next, using Rx to handle and manipulate events.

You can create an observable source from an even via the FromEvent factory method where you supply the event source (in our case a TextBox) and the name of the event. When you subscribe to this source, your code is executed each time the event is fired.

NOTE: If the hard-coded event string in the above example offends, there is a slightly more cumbersome FromEvent overload which allows you to specify add and remove handler actions explicitly.

Whilst the above example is not terribly exciting, now that we have the event packaged as an observable, we can perform Linq-style queries. In the following example, a Select projection operator is used to create an observable which contains just the text of the TextBox. This is then transformed via a second Select to create an observable which provides length changed ‘events’.

There is some powerful stuff going on here, from transforming the mouse move events into a more useable source of screen coordinates, composition of events via SkipUntil and TakeWhile, and the creation of deltas via Let and Zip.

I am not going to describe the above über example in much detail because although it demonstrates some really powerful techniques, it is just not the kind of problem that you typically have to solve when writing Silverlight (or WPF / WinForms) applications. Rather than focussing on how to composite multiple UI events, I will focus on how Rx can be used to orchestrate asynchronous web requests.

This first example application provides a Google Instant style search of Tweets, where Twitter is queried as you type. You can now save 2-5 seconds per Twitter search (see the above link if you do not get the reference).

The output is as expected; however, if you look at the numbers in brackets, which output the managed thread ID, something a little surprising is going on here. The logging at step #3 is on thread #1, which is the UI thread, however, the logging at step #5 is on thread #5. The Throttle step requires the use of a timer, so in order to free up the UI thread, the Rx library has marshalled our observations onto a threadpool thread.

It is great that Rx handles switching between threads for us, however Silverlight (and WPF / WinForms) controls have thread affinity, which means that they can only have their state updated from the UI thread. Fortunately Rx makes it easy to switch the thread that observes a source, via the various ObserveOn methods. There is also a WPF / Silverlight specific ObserveOnDispatcher method.

Adding a ListBox to our application, we can then output the text which we would like to search Twitter for by adding it to a collection bound to the ListBox:

The next step is to take the output above and perform a twitter search with it. There are a number of ways this can be achieved, a good approach if you are building a Twitter enabled application would probably be the TweetSharp .NET library. However, as I just want to perform a simple search, I decide to use the Twitter REST API directly. With this, API queries are performed without authentication via HTTP as a simple GET, e.g. http://search.twitter.com/search.atom?q=twitter, with the response provided in XML or JSON formats.

Silverlight provides two mechanisms for making web requests, WebClient, which provides a simple interface which returns the string response via an event marshalled onto the UI thread, and the more feature rich HttpWebRequest. The Rx library allows you to create an observable source from any class which has methods that follow the standard <a href="http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx">IAsyncResult</a> pattern. HttpWebRequest follows this pattern, so we will use it here.

With HttpWebRequest, you invoke BeginGetResponse supplying the callback method that is invoked when the response is returned. Within the callback, EndGetResponse is invoked in order to obtain the response.

The following code snippet shows how to query the twitter search API and read the result into a string:

With Rx, the FromAsyncPattern method can be used to create a function (i.e. an anonymous delegate) which when invoked supplies an observable source which performs the web request. Subscribing to this source will give the response. The Rx equivalent to the above is as follows:

The problem with the above twitterSearch function is that it will always perform the same search. We can fix that by creating a delegate that takes the search term as an input argument using one of the generically typed Func delegates:

The SelectMany operator is used to bind the input text to a new observable source that performs our twitter search. The ParseTwitterSearch method takes the resultant response string and uses a simple bit of Linq to XML to create a IEnumerable of Tweet objects.

The subscription takes this ‘collection’ of Tweet objects and sets them as the ItemsSource for our search results list box. The ToString method on the Tweet value object simply returns the Title, giving the following result:

Finally, we can jazz up the Twitter Instant application by applying a template to our list box and a scattering of value converters. I have added an animated loading indicator, and adjusted the list opacity whilst typing to show that the current search has been invalidated.

What I really like about the Rx approach to this sort of problem is that the program flow becomes a single observable pipeline, free from event handlers, state flags and clumsy thread marshalling logic.

NOTE: You might have spotted the race-condition in the above observable pipeline. If the user types ‘reactive’, pauses for a bit, causing a twitter search, then types ‘library’ resulting in a second twitter search, the result depends on which one returns first. Fortunately Rx has a few tricks up its sleeve here, if you read DevLabs: Reactive Extensions for .NET (Rx), you will find that the Switch or TakeUntil operators can be used to solve this problem.

British people love to talk about the weather, and there is nothing that gets us talking more than snow. This week, it has snowed ... a lot! One of my favourite mashups is Ben Marsh’s #uksnow, where you tweet your UK postcode together with how much snowfall there is in your area using the #uksnow twitter tag. Ben’s mashup adds little snow icons to a map to depict the tweets in realtime. I have been toying with the idea of creating a Silverlight clone of this mashup for a while, the Rx library and our recent excessive snowfall has given me the perfect excuse!

This time, the Observable.Timer extension method is used to create a ‘tick’ every thirty seconds. A slightly modified version of the searchTwitter function we saw in the previous example is used to query Twitter and the results are parsed. The tweets are then pushed onto the UI thread so that can be added to the view, the AddTweets method simply adds them to the list on the right of the UI, whilst ensuring that there is a maximum of 100 tweets present.

The modified searchTwitter function takes a lastId argument which is used to find all the Tweets since a given Id, so that we just add recent tweets with this hashtag to the list with each 30 second timer tick:

Note, because the observable pipeline is updating a field, we have to be careful about potential concurrency issues. In our case, the ObserveOnDispatcher operator means that the above code will always be called on the UI thread, however, the second step of our pipeline reads the value of _lastTweetId and will not be executed on the UI thread. If the timer ticks were reduced, this code could cause some problems if locking were not introduced.

Before moving onto the next few pipeline steps, we’ll look at the items being passed along the pipeline:

The first part of the pipeline creates Tweet objects, some of which might contain a postcode and snowfactor, so we are able to create UKSnowTweets from them. Finally, if geocoding is successful, we can create a GeoCodedUKSnowTweet.

After updating the last tweet ID, a SelectMany operator is used to project the IEnumerable<Tweet> items being passed down the pipeline into individual Tweet items, which are then passed to the next pipeline step. The next SelectMany uses the ParseTweetToUKSnow to match the postcode and snowfactors in the tweet. For example "Ben_fisher: #uksnow so51 1/10 hoping for a 10 :)" is a ‘valid’ uksnow tweet. The SelectMany has the nice side-effect that if a tweet cannot be parsed, it does not proceed to the next pipeline step. Here is the parsing method:

A UKSnowTweet is passed in, and observable returned, which when subscribed to, returns a GeoCodedUKSnowTweet if the geocode is a success. The ExtractLocationFromBingGeoCode method is again a simple bit of Linq to XML which parses the XML response.

Finally, we ObserveOnDispatcher and subscribe, with the resulting geocoded tweets pushed to our AddSnow method. This method adds a snow image as a child of a Bing Maps control, using the MapLayer attached properties to add it at the required latitude / longitude.

The Rx library is without a doubt a very clever and powerful tool, also the similarities with Linq certainly help the learning process. Many of the examples I have seen concentrate on UI event handling, which as I stated before is something I don’t find myself doing terribly often. Typically Silverlight applications consist of a ViewModel bound to the state of various UI controls, together with commanding, as a result you can write complex application without going anywhere near UI events. In my opinion, the real strength of Rx lies in orchestration of program flow. I really like the way that I was able to create the uksnow mashup as a single Observable query or pipeline, making the application flow clear concise and maintainable.

So ... what are your thoughts? Do you think you will use Rx? Is it a neat solution, or just a bit hard to get your head round?

I am also a Technical Evangelist at Scott Logic, a provider of bespoke financial software and consultancy for the retail and investment banking, stockbroking, asset management and hedge fund communities.

Interesting how when one thinks they already know LINQ, they see an example like this (from your code) and say... Wow! LINQ is even better than already thought! I've been reading the Reactive Extension's forums and see they've extended LINQ too. So, alas, one more "even better" for LINQ. Maybe in 2020 we'll all be programming everything in LINQ as it becomes its own Language! As far as RX, I think it's as powerful as LINQ. Both LINQ and RX take time to learn but I just love the results, and you've shown us a very nice usuage.

When I saw Rx I was immediately impressed with its power, however, I was not convinced that using it for UI events would really give me much benefit. I think it is much better suited to asynchronous communications. I am glad you liked the article