Scott Hanselman

Reactive Extensions (Rx) is now Open Source

November 6, '12 Comments [10] Posted in LINQ | Open Source
Sponsored By

A few years back I did a podcast with Erik Meijer about Reactive Extensions for .NET (Rx). Since then thousands of people have enjoyed using Rx in the projects and a number of open source projects like ReactiveUI (also on the podcast) have popped up around it. Even GitHub for Windows uses Reactive Extensions. In fact, GitHub uses Rx a LOT in their Windows product. My friend Paul at GitHub says they liked the model so much they made a Mac version!

“GitHub for Windows uses the Reactive Extensions for almost everything it does, including network requests, UI events, managing child processes (git.exe). Using Rx and ReactiveUI, we've written a fast, nearly 100% asynchronous, responsive application, while still having 100% deterministic, reliable unit tests. The desktop developers at GitHub loved Rx so much, that the Mac team created their own version of Rx and ReactiveUI, called ReactiveCocoa, and are now using it on the Mac to obtain similar benefits.” – Paul Betts, GitHub

Today, Microsoft Open Technologies announced the open sourcing of Reactive Extensions! You can get the code with git up on Codeplex at https://rx.codeplex.com. You can’t stop the open source train! Congrats to the team!

There’s a LOT included, so be stoked. It’s not just Rx.NET, but also the C++ library as well as RxJS for JavaScript! Now everyone gets to play with IObservable<T> and IObserver<T>.

  • Reactive Extensions:
    • Rx.NET: The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.
    • RxJS: The Reactive Extensions for JavaScript (RxJS) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in JavaScript which can target both the browser and Node.js.
    • Rx++: The Reactive Extensions for Native (RxC) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in both C and C++.
  • Interactive Extensions
    • Ix: The Interactive Extensions (Ix) is a .NET library which extends LINQ to Objects to provide many of the operators available in Rx but targeted for IEnumerable<T>.
    • IxJS: An implementation of LINQ to Objects and the Interactive Extensions (Ix) in JavaScript.
    • Ix++: An implantation of LINQ for Native Developers in C++

A great way to learn about why Rx is useful is to check out the Rx Koan’s project or to read the IntroToRx online e-book.

Why do I think Rx matters? It’s a way to do asynchronous operations on event streams. Rather than hooking up click events and managing state with event handlers all over, you effectively “query” an infinite stream of events with LINQ. You can declaratively sequence events…no flags, no state machine.

For example, here’s a dragging event created (composed) via Mouse button and Mouse move events:

IObservable<Event<MouseEventArgs>> draggingEvent =
from mouseLeftDownEvent in control.GetMouseLeftDown()
from mouseMoveEvent in control.GetMouseMove().Until(control.GetMouseLeftUp())
select mouseMoveEvent;

Even better, Rx makes it easier (or possible!) to create event-based tests that are asynchronous, like this example from Jafar Husain:

Rating rating = new Rating();
IObservable<Unit> test = // Unit is an object that represents null.
ObservableExtensions
.DoAsync(() => TestPanel.Children.Add(rating))
.WaitFor(TestPanel.GetLayoutUpdated()) // Extension method GetLayoutUpdated converts the event to observable
.DoAsync(() => rating.Value = 1.0) // Calls the Ignite EnqueueCallback method
.WaitFor( // waits for an observable to raise before going on
// listen to all the actual value change events and filters them until ActualValue reaches Value
rating
.GetActualValueChanged() // extension method that converts ActualValueChanged event to IObservable
.SkipWhile(actualValueChangedEvent => actualValueChangedEvent.EventArgs.NewValue != rating.Value))
// check to make sure the actual value of the rating item is set appropriately now that the animation has completed
.Assert(() => rating.GetRatingItems().Last().ActualValue == 1.0) // crawls the expression tree and makes a call to the appropriate Assert method

Test.Subscribe(() => TestPanel.Children.Remove(rating)); //run the test and clean up at the end.

There’s amazing Time-related operators that let you simulate events over time. Note the Buffer and Subscribe calls.

var myInbox = EndlessBarrageOfEmail().ToObservable();

// Instead of making you wait 5 minutes, we will just check every three seconds instead. :)
var getMailEveryThreeSeconds = myInbox.Buffer(TimeSpan.FromSeconds(3)); // Was .BufferWithTime(...

getMailEveryThreeSeconds.Subscribe(emails =>
{
Console.WriteLine("You've got {0} new messages! Here they are!", emails.Count());
foreach (var email in emails)
{
Console.WriteLine("> {0}", email);
}
Console.WriteLine();
});

You can use await and async, like in this example returning the number 42 after 5 seconds:

static async void button_Click()
{
int x = await Observable.Return(42).Delay(TimeSpan.FromSeconds(5));
// x with value 42 is returned after 5 seconds
label.Text = x.ToString();
}
I’m just showing you the parts that tickle me, but one could easily teach a 10 week university course on Rx, and I’m still a beginner myself!

Here’s some more resources to check out about Rx. Congrats to the team for their contribution to Open Source!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Wednesday, November 07, 2012 10:17:24 AM UTC
This is great Scott! Thanks!
Wednesday, November 07, 2012 6:17:53 PM UTC
I have read some of the Rx docs and like the idea. I am confused though. I cannot see if Rx replaces SignalR or when I would choose one over the other. Or maybe it replaces Knockout.js.
Wednesday, November 07, 2012 9:26:46 PM UTC
Fantastic! Congratulations to the Rx team. That's a huge achievement and a great contribution to open source.
Thursday, November 08, 2012 12:12:50 AM UTC
@Nicholas

Rx replaces neither SignalR nor Knockout.js. In fact, SignalR and Rx work great together. As an example, you could use Rx (.NET) to work with a series of server side events and then send transformed/filtered/etc events to the client using SignalR. You could also do thing the other way round, and let SignalR send a stream of events to a client application (say a browser app) and let Rx (the JavaScript flavor) filter/transform/etc those events directly on the client before displaying them to the user.
Paul Batum
Thursday, November 08, 2012 9:22:34 AM UTC
It's really great to hear someone other than Bart De Smet talking about RX. Not that I don't like Bart, it just makes me feel better to have a broader internal and external community discussing and evangelizing RX.
Ed Draper
Thursday, November 08, 2012 3:35:51 PM UTC
Good move - you should do this same with forgotten by Microsoft XNA...
Thursday, November 08, 2012 11:32:40 PM UTC
@Nicolas,

To echo @Paul's comment, we don't aim to replace Knockout.js at all where ko is really good at observable bindings for objects, RxJS is a more general purpose library which works across runtimes for more complex queries such as mapping, filtering, aggregation, etc.

You might want to think of more scenarios such as a dictionary suggest where you read input from the keyboard and query a service, while keeping in mind throttling the user's input so we don't flood the service, as well as handling things such as out of order results:
Autocomplete scenario

Another way to think about it is with rich events where you can combine together distinct events such as mouse down and mouse move until mouse up, and then you have a single object that you can pass around which now represents a mouse drag and drop event:
Drag and Drop Example

We have more examples here that you may be interested in looking at:
Examples


Matt
Matthew Podwysocki
Friday, November 09, 2012 8:02:18 PM UTC
I have been following RX for sometime now, but remained confused between async/await, event handling, and RX. When to use what where? My first thought would be change all the events in my application into an event stream, that I would then subscribe to as needed - like the windows message pump, and how windows receive messages. However, when I posted that, I recieved comments that using RX that way would be crazy.

Because RX is a weak reference, I thought it was a great way from worrying about de-referencing event handlers.

The next time I thought about RX, was with INotifyPropertyChanged events, and how binding works declaritively.

In both of these cases, I wonder why MS hasn't used RX deeper in the architecture - and allow subscriptions from the application layer.

Either way I would love to hear more shows about RX and how to categorize it's uses - perhaps with Paul Betts and understanding his learning curve with RX.
Richard Reukema
Friday, November 16, 2012 9:36:45 AM UTC
Why MS not add this into official .NET framework
victorwoo
Wednesday, November 21, 2012 1:49:26 PM UTC
Best MS doesn't put that into the .Net framework and better for MS to promote other additional frameworks on top of .Net, whether its their own or not.
Daniel Fernandes
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.