A collection of links and snippets to resources, samples, answers, people, videos, etc. related to Rx.Net.
Most of the blogs and videos are pretty dated but the core concepts still apply. The overall public API really hasn't changed much over the years, except for new operators and performance improvements.
Core Rx team at Microsoft: Erik Meijer, Brian Beckman, Wes Dyer, Bart De Smet, Jeffrey Van Gogh, and Matthew Podwysocki.
First preview release: 11/17/2009
First stable release: 06/29/2011
Open Sourced: 11/06/2012
Google searching tip: Because there are so many languages that have adopted Rx, there's a need to filter the results to dotnet. To achieve this, I always structure my query as "C# observable [my specific query]".
IntroToRx - If I had to name a single resource to help someone get started with Rx.Net, it would be this invaluable online book by Lee Campbell. Even after years of reactive programming, I find myself going back time and time again as a reference/reminder of some of the smaller details.
Book: Programming Reactive Extensions and LINQ
RxCookbook - Useful for learning how to utilize the power of Rx in common C# application scenarios, such as INotifyPropertyChanged and logging.
RxViz - interactive JavaScript with visualizations (I just wish a DotNet version of this existed)
RxMarbles - interactive visualizations
ReactiveX.io - Rx hub for all languages
Channel9 Videos, filtered by Rx
Channel9 Videos, filtered by Bart De Smit (one of the creators)
Reactive Extensions for .NET Developers with Michael Stonis (November 2018)
Why You Should Be Building Better Mobile Apps with Reactive Programming – Michael Stonis
UniRx playlist, but also includes intro to Rx theory and operators
- Members that return a sequence should never return null. This applies to IEnumerable and IObservable sequences. Return an empty sequence instead.
- Dispose of subscriptions.
- Subscriptions should match their scope.
- Always provide an OnError handler.
- Avoid breaking the monad with blocking operators such as First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault and ForEach.
- Avoid switching between monads, i.e. going from IObservable to IEnumerable and back to IObservable.
- Favor lazy evaluation over eager evaluation.
- Break large queries up into parts. Key indicators of a large query:
- nesting
- over 10 lines of query comprehension syntax
- using the into statement
- Name your queries well, i.e. avoid using the names like query, q, xs, ys, subject etc.
- Avoid creating side effects. If you must create side effects, be explicit by using the Do operator.
- Minimize* the use of the subject types. Rx is effectively a functional programming paradigm. Using subjects means we are now managing state, which is potentially mutating. Dealing with both mutating state and asynchronous programming at the same time is very hard to get right. Furthermore, many of the operators (extension methods) have been carefully written to ensure that correct and consistent lifetime of subscriptions and sequences is maintained; when you introduce subjects, you can break this. Future releases may also see significant performance degradation if you explicitly use subjects.
- Avoid creating your own implementations of the IObservable interface. Favor using the Observable.Create factory method overloads instead.
- Avoid creating your own implementations of the IObserver interface. Favor using the Subscribe extension method overloads instead.
- The subscriber should define the concurrency model. The SubscribeOn and ObserveOn operators should only ever precede a Subscribe method.
*If you check the source link above, you'll see I modified this point to say Minimize rather than Avoid. I did this because the opinions of some of the most respected Rx users on the web slightly differ when it comes to the degree of how much Subjects should be avoided. Here are some snippets of those opinions:
Lee Campbell: The reason I really don't like Subjects, is that is usually a case of the developer not really having a clear design on the problem. Hack in a subject, poke it here there and everywhere, and then let the poor support dev guess at WTF was going on. When you use the Create/Generate etc methods you are localizing the effects on the sequence. You can see it all in one method and you know no-one else is throwing in a nasty side effect. If I see a subject fields I now have to go looking for all the places in a class it is being used. If some MFer exposes one publicly, then all bets are off, who knows how this sequence is being used! Async/Concurrency/Rx is hard. You don't need to make it harder by allowing side effects and causality programming to spin your head even more.
Sergey Aldoukhov: People who frequent the RX forum know that E.Meijer does not like Subjects. While I have a deepest respect to RX creator's opinion, I have been using Subjects quite extensively in multiple projects for a couple of years and haven't had any architectural problem or a bug because of them.
Ani Betts: Erik Meijer is thinking in a purely functional way - Subjects are the mutable variables of Rx. So, in general usage he's right - using Subjects is sometimes a way to cop out of Thinking Functionally, and if you use them too much, you're trying to row upstream. However! Subject are extremely useful when you're interfacing with the non-Functional world of .NET. Wrapping an event or callback method? Subjects are great for that. Trying to put an Rx "interface" onto some existing code? Use a Subject!
Bart De Smet: Whenever you need to create an observable out of thin air, Observable.Create should be the first thing to think of. in a lot of cases, there's already a built-in primitive in Rx that does exactly what you need. For example, there's From* factory methods to bridge with existing concepts (such as events, tasks, asynchronous methods, enumerable sequence), some of which using a subject under the covers. For multicasting logic, there's the Publish, Replay, etc. family of operators.
James World: It's not so much that the use of Subject is bad - there has to be some way of "entering the monad" - that's the academic way of saying "get an IObservable". You need to start somewhere. The problem with Subject arises more when it's used from a subscription instead of chaining existing observables together. Subjects should just exist at the edges of your Rx machinery. If none of the provided entry points (e.g. FromEvent, FromEventPattern, FromAsync, Return, ToObservable and so on) work for you then using Subject is perfectly valid. And there's no need to add extra complexity just to facilitate using one of the above - most of them use subjects or subject-like constructs under the covers anyway.
Enigmativity: It's usually a good idea to avoid subjects.
Shlomo: Subjects aren't universally bad.
AsyncConversions: Start, ToAsync, FromAsyncPattern
ConstantTimeOperations: Return, Throw, Append, Prepend, StartWith
SynchronizationContextScheduler/ConstantTimeOperations: FromEvent, FromEventPattern
Iteration: Generate, Range, Repeat, TakeLast, ToObservable, ReplaySubject
TailRecursion: At the time of writing, I don't see this scheduler being used in the source code.
TimeBasedOperations: Buffer, Delay, DelaySubscription, Generate, Interval, Sample, Skip, SkipLast, SkipUntil, Take, TakeLast, TakeLastBuffer, TakeUntil, Throttle, TimeInterval, Timeout, Timer, Timestamp, Window
Useful advice for choosing schedulers
These are basically the names you'll see over and over again on Stack Overflow, answering Rx.Net questions. I've learned a ton from these guys.
James World @jamesw0rld
Lee Campbell @LeeRyanCampbell
Shlomo
Enigmativity
Ani Betts @anaisbetts
- Github
- Book: Programming Reactive Extensions and LINQ
- Stack Overflow - System.Reactive
- Stack Overflow - ReactiveUI
Brandon
Dave Sexton @IDaveSexton