Skip to main content

Rx Framework Part I - System.Reactive or the .NET Reactive Extensions (Rx) – Concepts and First Look

Recently, a lot of interest is bubbling up in the .NET community about reactive programming. This weekend I played around with this, and created a couple of POCs to get a feel. And I'm loving everything. Reactive extensions (Rx) is really cool, as it introduces lot of new possibilities. The .NET Rx or .NET Reactive extensions (System.Reactive.dll) recently appeared in the latest Silverlight tool kit drop. 

.NET Rx introduces two interfaces, IObservable and IObserver that "provides an alternative to using input and output adapters as the producer and consumer of event sources and sinks" and this will soon become the de-facto for writing asynchronous code in a declarative manner. Also, .NET Rx gives greater freedom to compose new events – you can create specific events out of general events. Let us see these aspects in a bit more detail.

Push and Pull Sequences

Here is a quick recap on Reactive programming - Consider a small example, result = var1 + var2. In a normal scenario, we expect the value of result to be independent of the variables, var1 and var2. Later the values of var1 and var2 might change, but the value of result may remain the same as it was at the time of the initial assignment.

But in a reactive scenario, the value of result is dependant on one or more of the variables we used to compute it’s value. i.e the value of, result would change or evolve over a period of time, based on the changes that might happen to var1 or/and var2.

Event based programming and asynchronous call backs are existing ways of doing Reactive programming in .NET. Consider how you handle a simple MouseMove operation in .NET using an event handler. Let us take a step back, and examine this a bit closer - The mouse cursor’s location value is changing over a period of time, and an event notifies you about that – or the source is pushing the value to you.

image

You may see the data we receive from these events as pieces of data that your event handler (the target) receive from a source over a period of time – a sequence. Also, you may instantly notice that the same is happening when you iterate over a collection, probably using a for loop. In that case too, you are receiving values from a source over a period of time, you are pulling the data. In both cases, the target is receiving the pieces of data from a source over a period of time, the difference is that the program is either pulling the data (a pull sequence) or the source or environment is pushing the data to the program (a push sequence).

What’s cool about .NET Rx?

.NET Rx team (this is not an official name) found that any push sequence can be viewed as a pull sequence as well – or they are Dual in nature. So this also means, there is a Duality between Iterator pattern IEnumerable/IEnumerator (pull) and Observable pattern (push) IObservable/IObserver.

So what is cool about about this duality? Anything you do with Pull sequences (read declarative style coding) is applicable to push sequences as well. Here are few aspects.

  • You can create Observables from existing events, enumerables etc  and then use them as first class citizens in .NET – i.e, you may create an observable from an event, and expose the same as a property.
  • As IObservable is the mathematical dual of IEnumerable, .NET Rx facilitates LINQ over push sequences like Events, much like LINQ over IEnumerables
  • It gives greater freedom to compose new events – you can create specific events out of general events.
  • .NET Rx introduces two interfaces, IObservable<T> and IObserver<T> that "provides an alternative to using input and output adapters as the producer and consumer of event sources and sinks"

If you want to dive a bit more deep in to this, watch this video where Eric Meijer explaining this duality. .NET Rx provides various extension methods for creating observables from Events, Enumerables etc.

Turning Events to Observables

The FromEvent method in System.Linq.Observable class will create an Observable, from  an event. This example shows how to create a observer for the Mouse left button down event, for a given control

  var mouseLeftDown=Observable.FromEvent<MouseButtonEventArgs>
          (mycontrol,"MouseLeftButtonDown");

The above example uses the following FromEvent extension method overload, in the Observable class

        public static IObservable<Event<TEventArgs>> 
	 	FromEvent<TEventArgs>(object target, string eventName) 
			where TEventArgs : EventArgs;

Now, as the event is an observable, we can subscribe to the same

mouseLeftDown.Subscribe
 (arg => Console.WriteLine(arg.EventArgs.ButtonState.ToString()));
Also, another overload for FromEvent exits in Observable class to convert an event to an Observable.
public static IObservable<Event<TEventArgs>> FromEvent<TDelegate,
                    TEventArgs>(Func<EventHandler<TEventArgs>, 
                             TDelegate> conversion, 
                             Action<TDelegate> addHandler, 
                             Action<TDelegate> removeHandler) 
			    where TEventArgs : EventArgs;

You may use this overload for explicitly specifying the event argument type and event handler type, and to enable compile time verification for the event name. Like,
 var mouseLeftDown= Observable.FromEvent<MouseButtonEventHandler, MouseButtonEventArgs>
                (   h => new MouseButtonEventHandler(h), 
                    h => el.MouseLeftButtonDown += h, 
                    h=> el.MouseLeftButtonDown -= h
                 );
Please notice that the type of mouseLeftDown is IObservable<Event<MouseButtonEventArgs>>. And as we discussed above, it is very much possible to use the mouseLeftDown variable they way you need. For example, you may pass mouseLeftDown to this method, where we again abstract out another Observable  just for the points, and subscribe to the same – and note that we use LINQ to do the same.
  
public void SubscribePoints
          (IObservable<Event<MouseButtonEventArgs>> mouseEvents)
{
	var points = from ev in mouseEvents
				 select ev.EventArgs.GetPosition(this);
	points.Subscribe(p => this.Title = "Location ="
                                     	+ p.X + "," + p.Y);
}
 

Further Reads

Shout it

Popular posts from this blog

Top 7 Coding Standards & Guideline Documents For C#/.NET Developers

Some time back, I collated a list of 7 Must Read, Free EBooks for .NET Developers, and a lot of people found it useful. So, I thought about putting together a list of Coding Standard guidelines/checklists for .NET /C# developers as well.As you may already know, it is easy to come up with a document - the key is in implementing these standards in your organization, through methods like internal trainings, Peer Reviews, Check in policies, Automated code review tools etc. You can have a look at FxCop and/or StyleCop for automating the review process to some extent, and can customize the rules based on your requirements.Anyway, here is a list of some good Coding Standard Documents. They are useful not just from a review perspective - going through these documents can definitely help you and me to iron out few hidden glitches we might have in the programming portion of our brain. So, here we go, the listing is not in any specific order.1 – IDesign C# Coding StandardsIDesign C# coding stand…

5 Awesome Learning Resources For Programmers (To help you and your kids to grow the geek neurons)

Happy New Year, this is my first post in 2012. I’ll be sharing few awesome learning resources I’ve bookmarked, and will be pointing out some specific computer/programming related courses I've found interesting from these resources.Also, thought about saving this blog post for my kids as well - instead of investing in these Child education schemes (though they are too small as of today, 2 years and 60 days respectively ). Anyway, personally my new year resolution is to see as much videos from this course collections (assuming I can find some free time in between my regular job && changing my babies diapers).1 – Khan AcademyAs I mentioned some time back, you and your kids are missing some thing huge if you havn’t heard about Khan Academy.  It is an awesome learning resource, especially if you want to re-visit your basics in Math, Science etc.With a library of over 2,600 videos covering everything from arithmetic to physics, finance, and history and 268 practice exercises, th…

Hack Raspberry Pi – How To Build Apps In C#, WinForms and ASP.NET Using Mono In Pi

Recently I was doing a bit of R&D related to finding a viable, low cost platform for client nodes. Obviously, I came across Raspberry Pi, and found the same extremely interesting. Now, the missing piece of the puzzle was how to get going using C# and .NET in the Pi. C# is a great language, and there are a lot of C# developers out there in the wild who are interested in the Pi.In this article, I’ll just document my findings so far, and will explain how develop using C# leveraging Mono in a Raspberry Pi. Also, we’ll see how to write few minimal Windows Forms & ASP.NET applications in the Pie as well.Step 1: What is Raspberry Pi?Raspberry Pi is an ARM/Linux box for just ~ $30. It was introduced with a vision to teach basic computer science in schools. How ever, it got a lot of attention from hackers all around the world, as it is an awesome low cost platform to hack and experiment cool ideas as Pi is almost a full fledged computer.  More About R-Pi From Wikipedia.The Raspberry Pi