views:

310

answers:

3

When would one choose to use Rx over TPL or are the 2 frameworks orthogonal?

From what I understand Rx is primarily intended to provide an abstraction over events and allow composition but it also allows for providing an abstraction over async operations. using the Createxx overloads and the Fromxxx overloads and cancellation via disposing the IDisposable returned.

TPL also provides an abstraction for operations via Task and cancellation abilities.

My dilemma is when to use which and for what scenarios?

+8  A: 

The main purpose of Rx is not to provide an abstraction over events. This is just one of its outcomes. Its primary purpose is to provide a composable push model for collections.

Th reactive framework (Rx) is based on IObservable<T> being the mathematical dual of IEnumerable<T>. So rather than "pull" items from a collection using IEnumerable<T> we can have objects "pushed" to us via IObservable<T>.

Of course, when we actually go looking for observable sources things like events & async operations are excellent candidates.

The reactive framework naturally requires a multi-threaded model to be able to watch the sources of observable data and to manage queries and subscriptions. Rx actually makes heavy use of the TPL to do this.

So if you use Rx you are implicitly using the TPL.

You would use the TPL directly if you wish direct control over your tasks.

But if you have sources of data that you wish to observe and perform queries against then I thoroughly recommend the reactive framework.

Enigmativity
+2  A: 

Some guidelines I like to follow:

  • Am I dealing with data that I don't originate. Data which arrives when it pleases? Then RX.
  • Am I originating computations and need to manage concurrency? Then TPL.
  • Am I managing multiple results, and need to choose from them based on time? Then RX.
Scott Weinstein
+1  A: 

I like Scott W's bullet points. To put some more concrete examples in Rx maps really nicely to

  • consuming streams
  • performing non-blocking async work like web requests.
  • streaming events (either .net events like mouse movement OR Service Bus message type events)
  • Composing "streams" of events together
  • Linq style operations
  • Exposing data streams from your public API

TPL seems to map nicely to

  • internal parallelisation of work
  • performing non-blocking async work like web requests
  • performing work flows and continuations

One thing I have noticed with IObservable (Rx) is that it becomes pervasive. Once in your code base, as it will no doubt be exposed via other interfaces, it will eventually appear all over your application. I imagine this may be scary at first but most of the team is pretty comfortable with Rx now and love the amount of work it saves us.

IMHO Rx will be the dominant library over the TPL as it already is supported in .NET 3.5, 4.0, Silverlight 3, Silverlight 4 and Javascript. This means you effectively have to learn one style and it is applicable to many platforms.

Lee Campbell