Bart De Smet: Inside Rx 2.0 Beta

Play Bart De Smet: Inside Rx 2.0 Beta
Sign in to queue


Rx v2.0 Beta is here! Who better to tell us all about it - and in great detail at the whiteboard - than Bart J. F. De Smet. This is a long interview, so take your time. Watch it in parts or at one sitting. There was no easy way to dice this up into separate videos, so we give it to you as it happened - in one take. As usual, Bart's explanations are thorough and clear. Enjoy. Learn. Rx has a come a long way and there's a great deal of new, improved reactive goodness in 2.0! Congratulations to Bart and team. Smiley

Highlights of this release:

Support for .NET 4.5 Beta.

Support for .NET for Metro style applications and Windows 8 Consumer Preview.

Rx Portable Library Beta.

Await support on IObservable<T>.

Async variants of various operators.

Scheduling using async methods.

Generalized time-based operators.

Improved performance.

You can read much more about this release in Bart's (lengthy) blog post, including download links and installation instructions.



Right click to download this episode

The Discussion

  • User profile image
    Maddus Mattus

    Simply awesome!

    I love Rx!

    Events are so dead Smiley

  • User profile image

    Awesome  Cool

    Nice Job Bart 

    Rx Live

  • User profile image
    El Bruno

    Great material !!!


  • User profile image

    The integration between Tasks and Observables, using async/await, is absolutely fantastic.  It really seems natural to combine the two as demonstrated by Bart. 

    The enlightenments are a great way to deal with platform specific capabilities, and I imagine it's facilitated by the compositionality gained by using LINQ - is that correct?

    I'm still working my way through the video and Bart's blog post ... I was definitely into the prime number filter, in the blog post because I was working on one recently - and using Rx for it in fact, and Bart's solution using Rx with await/async was just so much fun to read (and better) I was absorbed into that sample until 2:30am last night.  Smiley



  • User profile image

    Hm, I have the impression that this thing is somehow getting a little bit out of control. Where are the real use-cases ? How is the debugging experience ? I'm really not sure about it and I'm wondering people like Anders think about it.

  • User profile image

    @Mike:  Rx represents a pattern, a style, a methodology and mechanism for stream-based, asynchronous programming using LINQ operators. Rx works with simpler, single value async models seamlessly (so, with C# async/await).

    No offense, but I wouldn't rely on somebody else's opinion about something while forming your own. Granted, it's Anders, but still...  

    Go ahead and watch some of the C9 interviews with Anders ( Rx typically comes up as I generally see to it that he talks about it Smiley ). Most recently, you can see/hear Anders talking about Rx here


  • User profile image
    Christoph Burgdorf

    @Mike The debugging experience just got a whole lot better with this release. Have you gotten to the point where Bart talks about the call stacks? Those changes help you a lot in cases of trouble...

  • User profile image

    @Mike: There are a whole bunch of use cases. I'm surprised to learn about new customers using Rx in different ways every week. Most recently:

    • Data center monitoring scenarios - e.g. computing moving aggregates of CPU utilization, noticing peaks, etc.
    • Sensor and signal processing systems - e.g. collecting and processing data in smart grids, network centers, etc.
    • Robotics where queries over sensor inputs control servos etc. - e.g. we've seen queries being compiled into embedded code.
    • GPS processing systems to tame events of long/lat pairs - e.g. filter out noise, correlate with other data stores, etc.
    • Intrusion detection systems by processing historical logs and real-time data - e.g. logs of requests / IP address, try to find suspicious outliers.
    • Blending UI events with asynchronous requests to web services etc. - e.g. take input in a text box and launch async web calls for completion etc.

    The spectrum of places used has also grown signficantly. We started off by going into Windows Phone 7 as an API to help users process sensor data (accelerometer, GPS, etc.). In full desktop CLR, we've seen adoption ranging from client UI scenarios to server/datacenter workloads. We're seeing an increasing interest in the embedded space as well, including robotics. And we have Rx for JavaScript used in both client and server scenarios (e.g. node.js).

    Stay tuned and you'll see us "eat our own dogfood" in various places. Quite a few products today are shipping "powered by Rx" (most lately PowerView in SQL Server 2012, various online services in Bing, but also yet-unannounced projects), and the number is growing fast.

    With regards to debuggability, we've done a lot of work in this release to make callstacks readable, approachable, and understandable (see the blog post). This is just the end of the beginning of work we're doing in this field. So again, stay tuned!

  • User profile image

    Great improvements to Rx Bart.  Keep the good stuff coming...

    Over the years, following Rx videos on C9; it has helped me to think outside IEnumerable box; to solve problems in more declarative/reactive way using Rx Operators.

    With tremendous performance improvements; Rx just got a great boost for real-time systems (which can't be build with IEnumerable mind-set).

  • User profile image

    @WinInsider: Rock and roll.


  • User profile image
    Maddus Mattus

    @bdesmet: Would love to see the base libraries using observables instead of events.

    I'm having to write all kinds of extension messages around them just to be able to use the observable.

  • User profile image

    Wow, looks like a great amount of work...

    Just tried it via NuGet and I got one question:

    What's the purpose of the namespace System.Reactive.Linq.Observαble (note the 'alpha' instead of an 'a')? It contains internal classes that seem to correspond to the operators defined in the static class System.Reactive.Linq.Observable (with a Latin a).

  • User profile image

    @Maddus Mattus: Observables come at a slightly higher cost than events, e.g. due to the need for an IDisposable "subscription handle". So, having events at the core isn't a bad thing either. For "non-complex event processing" scenarios, a simple event handler often suffices (e.g. the form closing event to pop up a "do you want to save" dialog).

    What you likely want is a smoother way to convert an event into an observable sequence, just like F# has an implicit conversion allowing this (see here and here for starters).

  • User profile image

    @Novox: You're seeing an internal namespace with a Greek alpha in its name to make the call stack look exactly like the methods you wrote. We can't have inner classes such as Where nested inside Observable, because there's already a method with that name. So, the closest approximation was an Observαble namespace with classes such as Where in it.

    Unfortunately, the namespace shows up in IntelliSense at this point, due to some complexities around the IDE's handling of InternalsVisibleTo. We're aware of this problem and are looking into it.

  • User profile image
    Maddus Mattus

    @bdesmet: Thanks Bart! Smiley Will check out the links,..

    Is it still less expensive when one takes into account that nobody ever de-subscribes their handlers?

    When I discovered Rx, normal events seemed like a hack Wink

  • User profile image

    @Maddus Mattus: Still need to allocate the IDisposable. This said, not that big of a deal, especially if you don't ever need to unsubscribe, meaning the object becomes food for a Gen0 collection.

    As soon as you start composing events, the benefits far outweigh the cost. A lot of the composition of Rx builds on the ability to compose subscriptions. Subscribing to the merge of N sources means returning an IDisposable that holds on to the underlying N source subscriptions. It's as simple as that.

    If you'd measure all sorts of performance metrics in real-world scenarios, I doubt the disposable object graph will show up as a relevant influence. (Btw, we have many IDisposable implementations internally in Rx, also to allow for reuse of objects.) It definitely didn't in the Rx v2.0 Beta analysis of performance. Also, typically there's 1 subscription for a whole bunch of events flowing through the pipeline: 1 <<<<< N.

    To conclude, my remark is mostly about the debate whether or not observables are a primitive or an abstraction over a primitive. Just like delegates are first-class representations of methods, observables are first-class representations of events (which are method pairs for our purposes). In this analogy, one doesn't "convert" (e.g. through method group conversion in C#, see ECMA 334, section 13.6) a method into a delegate unless you want to do a more functional style composition (e.g. LINQ to Objects heavily relies on delegates). The same holds for observables, with the only difference being a bit more friction to convert an event to its first-class representation (i.e. there's no method group equivalent for event members).

  • User profile image
    Maddus Mattus

    @bdesmet: Thanks for taking the time to answer my ramblings Smiley

    You, Erik and Brian are always fun to watch and learn from!

    Keep up the good stuff!

  • User profile image
    Bnaya Eshet

    You have done an amazing job.

  • User profile image

    Great work. Very interesting!

    I'm curious about how these platform specific "enhancements" are enabled, are they loaded via reflection or are there any special tricks to override the default behaviour?

    I think there are many instances where this will be an issue in the following years and if there is a standard way to leverange portable core functionality with platform specific overrides it would make an interesting article/video.

  • User profile image

    @Kim: The platform enhancements are loaded through a Type.GetType call, followed by an instantiation of the discovered type (if any). The resulting object is cached so subsequent uses of the service don't take a performance hit.

    The BCL/CLR teams are aware of the need for such tricks in some types of APIs, and we may see more guidance or helper functionality to address this going forward (no promises implied in this statement). For a lot of Portable Libraries though, one can live without such mechanisms. Think about class libraries for a data model that can be reused across Windows Phone, Metro, Silverlight, classic desktop, etc.

  • User profile image


    I just did the VS 11 Beta "async lab" from the msdn on:

    I would love to get a tutorial on how to best refactor the results of that course to use RX 2.0 beta!
    That would be a great starting point for RX newbies like me Smiley

    Any hope someone can do that?

    Or is there already a good tutorial for this?

  • User profile image

    Brilliant work Bart. I really like the perf improvement stuff you have done. It is cool to see a conceptual evolution from your MiniLinq concept to Rx v1 to the optimisations you are doing in v2 (eg Buffer/Merge/SelectMany/Either).

    Call stack imrpvements are super welcome addition too. Are there any tricks that your operators do to know that they are part of a "safe" chain? ie that Select doesnt need to protect itself from Where, but potentially does from my own custom operator?


    @genteldepp: has an introduction to Rx, but for V1. It is currently undergoing a total rewrite...hope to be out soon. Hope it helps.

  • User profile image

    @LeeCampbell: At this point, there are no magic tricks to know whether an operator is part of a "safe" chain. What's really going on here is a different approach to writing operators, based on custom observer implementations rather than the anonymous implementation approach through lambda-based Subscribe calls to the sources of the operator.

    In order to ensure "global" safety, there's a minimal amount of cheap safeguarding based on swapping out observers for mute ones as soon as an operator's input reaches a terminal state. So, multiple terminal messages (invalid from the grammar's point of view) are silenced but the first one, and the place this happens is inside the custom operator noticing this (rather than in the Subscribe method's wrapping of the observer in the past).

    As for concurrent notifications (which are invalid too), there has never been true safeguarding against this, so inputs are assumed to be safe. Only when an operator has to deal with multiple sources, it will do proper orchestration internally (e.g. Merge has to ensure we never talk to the outgoing observer in a concurrent manner), using locks or other approaches. However, when an ill-behaved producer is in the mix, behavior is undefined (e.g. a Subject<T> that exhibits concurrent messages). In case such a producer exists, one has to safeguard the pipeline using Synchronize.

    When implementing sources or custom operators, we recommend to use ObservableBase<T> and Observable.Create, respectively. Those are the safest way to get things right. In fact, for custom operators, the use of composition of existing operators is a good start. Going forward, we may provide more advanced "power user" facilities to write more efficient custom operators using techniques similar to the ones we're using internally now. However, with power comes responsibility, so users of such primitives and implementation patterns need to have a thorough understanding of expectations with regards to observable sequences, the observer grammar, etc.

Add Your 2 Cents