Reactive Extensions is More Than Async

Tags: Rx, Reactive, Linq2Rest

A short while ago I asked for some feedback for the latest addition to the Linq2Rest project, Linq2Rest.Reactive, and the feedback I got started some thinking about why I was going for one solution over another. Peter Goodman asked a good question, when he asked why I did not merely wrap the LINQ query in a Task<T>. My initial thought was that the reactive addition to Linq2Rest would be an asynchronous version of querying REST services, but when you think about it, then Rx is more than merely an asynchronous version of LINQ.

A lot is being said and written about asynchronous programming, and with the introduction of the new async/await keywords in C# 5 everyone will soon be doing it. Linq2Rest.Reactive is also about asynchronous querying, but if that was the only problem to solve, I would take Pete's suggestion and create a wrapper for a LINQ query. I did that in the base Linq2Rest package with the ExecuteAsync extension method to an IQueryable<T>.

Asynchronous programming is hard. Async/await will make writing asynchronous code easier, but there are still many things to consider about threading, execution paths and availability. If you don't understand asynchronicity and what deferred execution is, then async/await won't help you anymore than a calculator will help you if you don't understand math. Yes, you can get a result. You may even get a reasonably good result, but if you don't understand why, then you will have a hard time using it in combination with other things.

Reactive Extensions (Rx) offers more than just a way to get results asynchronously. With Rx you get the ability to compose and merge queries. This allows for richer queries as well as a more declarative way to build up the data to be consumed. On top of this you get the option to decide which thread context you wish to handle your data on. Instead of working this out for yourself, you can leverage the brains of the Rx team when it comes to synchronizing your data.

One of the primary use cases for Rx is working with streams of data. As Peter rightly pointed out, reactive programming implies observing something more than a single result set, because this is effectively what an asynchronous query execution is. Since REST is based on a polling model, it is by the nature of things not compatible with streams. It is much more like awaiting a single burst of results when queried. Setting up an observable (which is presumed to be longer lived) may seem a bit excessive. If on the other hand the single result is your only concern, then it does seem more suitable to use asynchronous execution.

However if the data you are working with is continuous, then it may make sense to set up an observable context, even though the data has to be fetched using polling. This could be the case with an RSS feed, which is assumed to be updated continually. There are lots of other examples of data, such as financial data, which changes with regular intervals, which can be polled. With the advent of web sockets continuous connections will become more frequent, and so will web based data streams. Linq2Rest is designed to not care whether you are using polling or long-lived connections.

Going back to the original point of the post, then async querying may work well for many scenarios, and does seem the logical default choice when it comes to REST based data. But from a querying perspective, reactive extensions provide an alternate approach to working with the data, which may become more popular with the growth of long lived connections. Whichever you chose will depend on the data you are working with and how you intend to use it. For me it is important that Linq2Rest be able to support either type of usage. The important thing is that you understand why you are choosing one over the other.

Latest Tweets