slides license: creative commons attribution non-commercial share alike see...

54
Rx: your prescription to cure asynchronous programming blues Slides license: Creative Commons Attribution Non-Commercial Share Alike See http ://

Upload: shania-benham

Post on 31-Mar-2015

220 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Rx: your prescription to cure asynchronous programming blues

Slides license: Creative Commons Attribution Non-Commercial Share AlikeSee http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Page 2: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Mission statement

Rx is a library for composing asynchronous and event-based

programs using observable collections.

( 𝑓 ◦𝑔)(𝑥 )= 𝑓 (𝑔(𝑥 ))

Queries? LINQ?

Too hard today…

Download at MSDN DevLabs• .NET 2.0, .NET 4.0, Silverlight• JavaScript, more…?

Page 3: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerable<out T>{ IEnumerator<T> GetEnumerator();}

interface IEnumerator<out T> : IDisposable{ bool MoveNext(); T Current { get; } void Reset();}

Essential InterfacesEnumerables – a pull-based world

You could get stuck

C# 4.0 covariance

Page 4: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Essential InterfacesEnumerables – a pull-based world

You could get stuck

C# 4.0 covariance

(Waiting to move next)

moving on

Page 5: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Mathematical dualityBecause the Dutch are (said to be) cheap

Electricity: inductor and capacitor

Logic: De Morgan’s Law

Programming?

¬ ( 𝐴∧𝐵 )≡¬𝐴∨¬𝐵 ¬ ( 𝐴∨𝐵 )≡¬𝐴∧¬𝐵

Source:

http://s

martcanucks.c

s

Page 6: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

What’s the dual of IEnumerable?The recipe to dualizationhttp://en.wikipedia.org/wiki/

Dual_(category_theory)

Reversing arrows…Input becomes output and

vice versaMaking a U-turn

in synchrony

Page 7: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerable<T>{ IEnumerator<T> GetEnumerator();}

interface IEnumerator<T> : IDisposable{ bool MoveNext(); T Current { get; } void Reset();}

What’s the dual of IEnumerable?Step 1 – Simpler and more explicit

GetEnumerator(void);

MoveNext(void); throws Exception;GetCurrent(void); C# didn’t borrow

Java checked exceptions

Page 8: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerable<T>{ }

interface IEnumerator<T> :{ bool MoveNext(void) throws Exception; T GetCurrent(void);}

What’s the dual of IEnumerable?Step 1 – Simpler and more explicit

IDisposable

( & )IEnumerator<T> GetEnumerator(void);We really got an

enumerator and a disposable

Page 9: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface{ (IDisposable & );}

interface IEnumerator<T>{ bool MoveNext(void) throws Exception; T GetCurrent(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

voidIEnumerator<T>

IEnumerableDual<T>IEnumerable<T>

) GetEnumerator(Set

Will only dualize the synchrony

aspect

Page 10: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(IEnumerator<T> x);}

interface IEnumerator<T>{ bool MoveNext(void) throws Exception; T GetCurrent(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

This is an output too

Page 11: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(IEnumerator<T> x);}

interface IEnumerator<T>{ (bool | Exception) MoveNext(void); T GetCurrent(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

Discrete domain with true and

false

Page 12: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(IEnumerator<T> x);}

interface IEnumerator<T>{ (true | false | Exception) MoveNext(void); T GetCurrent(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

If you got true, you really got a T

T

Page 13: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(IEnumerator<T> x);}

interface IEnumerator<T>{ (T | false | Exception) MoveNext(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

If you got false, you really got

void

void

Page 14: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(}

interface{ );}

What’s the dual of IEnumerable?Step 2 – Swap input and output

(T | void | Exception)

MoveNext(void

But C# doesn’t have discriminated unions…

Let’s splat this into three methods instead!

Got

IEnumeratorDual<T>IEnumerator<T>

IEnumeratorDual>);IEnumerator<T> x);

Page 15: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IEnumerableDual<T>{ IDisposable SetEnumerator(IEnumeratorDual<T>);}

interface IEnumeratorDual<T>{ void GotT(T value); void GotException(Exception ex); void GotNothing(void);}

What’s the dual of IEnumerable?Step 2 – Swap input and output

Page 16: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IObservable<T>{ IDisposable SetObserver(IObserver<T> observer);}

interface IObserver<T>{ void GotT(T value); void GotException(Exception ex); void GotNothing();}

What’s the dual of IEnumerable?Step 3 – Consult the Gang of Four…

Sou

rce:

http

://am

azo

n.co

m

Page 17: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IObservable<out T>{ IDisposable SetObserver(IObserver<T> observer);}

interface IObserver<in T>{ void GotT(T value); void GotException(Exception ex); void GotNothing();}

What’s the dual of IEnumerable?Step 4 – Variance annotations

Used to detach the observer…

Do you really know C# 4.0?

Page 18: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IObservable<out T>{ IDisposable Subscribe(IObserver<T> observer);}

interface IObserver<in T>{ void OnNext(T value); void OnError(Exception ex); void OnCompleted();}

What’s the dual of IEnumerable?Step 5 – Color the bikeshed (*)

(*) Visit http://en.wikipedia.org/wiki/Color_of_the_bikeshed

Page 19: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

interface IObservable<out T>{ IDisposable Subscribe(IObserver<T> observer);}

interface IObserver<in T>{ void OnNext(T value); void OnError(Exception ex); void OnCompleted();}

Essential InterfacesObservables – a push-based world

You could get flooded

C# 4.0 contravariance

Page 20: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Essential InterfacesSummary – push versus pull

Environment

MoveN

ex

tGot next?

Application

On

Next

Have next!

IEnumerable<T>

IEnumerator<T>

IObservable<T>

IObserver<T>

Inte

racti

ve R

eactiv

e

Page 21: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Essential Interfaces

demo

Page 22: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Getting Your ObservablesPrimitive constructors

Observable.Empty<int>()

Observable.Return(42)

Observable.Throw<int>(ex)

OnCompleted

OnNext

OnError

Observable.Never<int>()

new int[0]

new[] { 42 }

Throwing iterator

Iterator that got stuckNotion of

time

Page 23: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Getting Your ObservablesObserver (and enumerator) grammar

OnNext* [ OnError | OnCompleted ]

Observable.Range(0, 3)

OnNext(0)

OnNext(1)

OnNext(2)

Enumerable.Range(0, 3)

yield 0 yield 1 yield 2

Page 24: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

o = Observable.Generate( 0, i => i < 10, i => i + 1, i => i * i);

o.Subscribe(x => { Console.WriteLine(x);});

Getting Your ObservablesGenerator functions

e = new IEnumerable<int> { for (int i = 0; i < 10; i++) yield return i * i;};

foreach (var x in e) { Console.WriteLine(x);}

Hypothetical anonymous iterator

syntax in C#

Synchronous

Asynchronous

A variant with time notion exists

(GenerateWithTime)

Page 25: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted();});

IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); });

Getting Your ObservablesCreate – our most generic creation operator

C# doesn’t have anonymous interface implementation, so we provide various extension methods

that take lambdas.

C# 4.0 named parameter syntax

Page 26: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted();});

IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); });

Thread.Sleep(30000); // Main thread is blocked…

Getting Your ObservablesCreate – our most generic creation operator

F10

Page 27: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted();});

IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); });

Thread.Sleep(30000); // Main thread is blocked…

Getting Your ObservablesCreate – our most generic creation operator

F10

Page 28: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted();});

IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); });

Thread.Sleep(30000); // Main thread is blocked…

Getting Your ObservablesCreate – our most generic creation operator

F5

Page 29: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted();});

IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); });

Thread.Sleep(30000); // Main thread is blocked…

Getting Your ObservablesCreate – our most generic creation operator

Breakpoint got hit

Page 30: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Getting Your Observables

demo

Page 31: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

form1.MouseMove += (sender, args) => {

if (args.Location.X == args.Location.Y) // I’d like to raise another event};

form1.MouseMove -= /* what goes here? */

Bridging Rx with the WorldWhy .NET events aren’t first-class…

Hidden data sourceHow to pass

around?

Lack of composition

Resource maintenance?

Page 32: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IObservable<Point> mouseMoves = Observable.FromEvent(frm, "MouseMove");var filtered = mouseMoves .Where(pos => pos.X == pos.Y);

var subscription = filtered.Subscribe(…);subscription.Dispose();

Bridging Rx with the World…but observables sequences are!

Source of Point values

Objects can be passed

Can define operators

Resource maintenance!

Page 33: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

FileStream fs = File.OpenRead("data.txt");byte[] bs = new byte[1024];fs.BeginRead(bs, 0, bs.Length, new AsyncCallback(iar => { int bytesRead = fs.EndRead(iar); // Do something with bs[0..bytesRead-1] }), null);

Bridging Rx with the WorldAsynchronous methods are a pain…

Hidden data source

Really a method pair

Lack of composition

Exceptions?

Synchronous

completion?

Cancel?

State?

Page 34: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Bridging Rx with the World…but observables are cuter!

FileStream fs = File.OpenRead("data.txt");Func<byte[], int, int, IObservable<int>> read =

Observable.FromAsyncPattern<byte[], int, int, int>( fs.BeginRead, fs.EndRead);

byte[] bs = new byte[1024];read(bs, 0, bs.Length).Subscribe(bytesRead => { // Do something with bs[0..bytesRead-1]});

Tip: a nicer wrapper can easily be made using various

operators

Page 35: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Bridging Rx with the WorldThe grand message

We don’t replace existing asynchrony:

.NET events have their usethe async method pattern is fine tooother sources like SSIS, PowerShell, WMI, etc.

but we…unify those worldsintroduce compositionalityprovide generic operators

hence we…build bridges!

Page 36: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Bridging Rx with the WorldTerminology: hot versus cold observables

Cold observables

Hot observables

var xs = Observable.Return(42);

xs.Subscribe(Console.WriteLine); // Prints 42xs.Subscribe(Console.WriteLine); // Prints 42 again

Triggered by subscription

var mme = Observable.FromEvent<MouseEventArgs> (from, "MouseMove");

mme.Subscribe(Console.WriteLine);

Mouse events going before subscription

Page 37: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Bridging Rx with the World

demo

Page 38: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and QueryingConcurrency and synchronization

What does asynchronous mean?Greek:

a-syn = not with (independent from each other)chronos = time

Two or more parties work at their own pace

Need to introduce concurrency

Notion of ISchedulervar xs = Observable.Return(42, Scheduler.ThreadPool);xs.Subscribe(Console.WriteLine);

Will run on the source’s

scheduler

Parameterization of

operators

Page 39: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and QueryingConcurrency and synchronization

Does duality apply?Convert between both worlds

“Time-centric” reactive operators:

// Introduces concurrency to enumerate and signal…var xs = Enumerable.Range(0, 10).ToObservable();

// Removes concurrency by observing and yielding…var ys = Observable.Range(0, 10).ToEnumerable();

source1source2source1.Amb(source2)

Race!

Page 40: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and QueryingConcurrency and synchronization

• IScheduler• WPF dispatcher• WinForms control• SynchronizationCont

ext

How to synchronize?

Compositionality to the rescue!

var xs = Observable.Return(42, Scheduler.ThreadPool);xs.Subscribe(x => lbl.Text = "Answer = " + x);

xs.ObserveOn(frm).Subscribe(x => lbl.Text = "Answer = " + x);

Page 41: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and QueryingStandard Query Operators

Observables are sources of dataData is sent to you (push based)Extra (optional) notion of time

Hence we can query over them// Producing an IObservable<Point> using Selectvar mme = from mm in Observable.FromEvent<MouseEventArgs>( form, “MouseMove”) select mm.EventArgs.Location;

// Filtering for the first bisector using Wherevar res = from mm in mme where mm.X == mm.Y select mm;

Page 42: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and QueryingPutting the pieces together

ReactTextChanged Dictionary

web service

Asynchronous request

ReactionReactiveReactor

IObservable<string>

IObservable<DictionaryWord[]>

Data binding

on UI thread

$$$

Page 43: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

// IObservable<string> from TextChanged eventsvar changed = Observable.FromEvent<EventArgs>(txt, "TextChanged");var input = (from text in changed select ((TextBox)text.Sender).Text); .DistinctUntilChanged() .Throttle(TimeSpan.FromSeconds(1));

// Bridge with the dictionary web servicevar svc = new DictServiceSoapClient();var lookup = Observable.FromAsyncPattern<string, DictionaryWord[]> (svc.BeginLookup, svc.EndLookup);

// Compose both sources using SelectManyvar res = from term in input from words in lookup(term) select words;

Composition and QueryingSelectMany – composition at its best

input.SelectMany(term => lookup(term))

Page 44: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Composition and Querying

demo

Page 45: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

input

ReactReacti

ve

Service call 1

Service call 2

UI data binding

Reactive

ReactionReactiveReactor

|R|Re|Rea|Reac|React|React|Reacti|Reactiv|Reactive|

ReactiveReactionReactiveReactor

Composition and QueryingAsynchronous programming is hard…

Source: http://scrapetv.com

Page 46: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

input

ReactReacti

ve

Service call 1

Service call 2

UI data binding

Reactive

ReactionReactiveReactor

|R|Re|Rea|Reac|React|React|Reacti|Reactiv|Reactive|

Reactive

Composition and QueryingFixing out of order arrival issues

Cancel call 1

TakeU

ntil

Page 47: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

// IObservable<string> from TextChanged eventsvar changed = Observable.FromEvent<EventArgs>(txt, "TextChanged");var input = (from text in changed select ((TextBox)text.Sender).Text); .DistinctUntilChanged() .Throttle(TimeSpan.FromSeconds(1));

// Bridge with the dictionary web servicevar svc = new DictServiceSoapClient();var lookup = Observable.FromAsyncPattern<string, DictionaryWord[]> (svc.BeginLookup, svc.EndLookup);

// Compose both sources using SelectManyvar res = from term in input from words in lookup(term).TakeUntil(input) select words;

Composition and QueryingApplying the TakeUntil fix

// Alternative approach for composition using:// IObservable<T> Switch<T>(IObservable<IObservable<T>> sources)var res = (from term in input select lookup(term)) .Switch();

Very local fix

Hops from source to source

Page 48: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Fixing asynchronous issues

demo

Page 49: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Rx for JavaScript (RxJS)

Parity with Rx for .NETSet of operatorsTaming asynchronous JS

JavaScript-specific bindings

jQueryExtJSDojoPrototypeYUI3MooToolsBing APIs

Page 50: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Rx for JavaScript (RxJS)

$("#input").ToObservable("keyUp") .Throttle(250) .Select(function(ev) { return query($(ev.target).text()); }) .Switch() .Select(function(result) { return formatAsHtml(result); }) .Subscribe( function(results) { $("#results").html(results); }, function(error) { $("#results").html("Error: " + error); });

Page 51: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Rx for JavaScript (RxJS)

demo

Page 52: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

IEnumerable<T>

E.g. LINQ to Objects

IObservable<T>

E.g. LINQ to Events

IQueryable<T>

E.g. LINQ to SQL

Fix

ed

(MS

IL)

Tran

sla

tab

le(E

xp

ressio

n

trees)

ToQueryable

ToObservable

ToEnumerable

AsQ

uery

able

AsE

nu

mera

ble A

sQb

serv

able

AsO

bse

rvable

Pull(interactive)

Push(reactive)

Concu

rren

cy

(ISch

edul

er)

LINQ to *.*

What?

Wher

e?

How

?

Worker pools Message loopsThreads Distributed

Duality

Hom

o-

icon

ic

IQbservable<T>E.g. LINQ to PowerShell

ToQbservable

Page 53: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Mission accomplished

Rx is a library for composing asynchronous and event-based

programs using observable collections.

( 𝑓 ◦𝑔)(𝑥 )= 𝑓 (𝑔(𝑥 ))

Queries! LINQ!

Way simpler with Rx

Download at MSDN DevLabs• .NET 2.0, .NET 4.0, Silverlight• JavaScript, more…?

Page 54: Slides license: Creative Commons Attribution Non-Commercial Share Alike See //creativecommons.org/licenses/by-nc-sa/3.0/legalcode

Related ContentHands-on Labs

Two flavors:Curing the asynchronous blues with the Reactive Extensions (Rx) for .NETCuring the asynchronous blues with the Reactive Extensions (Rx) for JavaScript

Both can be found via the Rx forums

Rx team web presenceRx team blog – http://blogs.msdn.com/rxteamDevLabs – http://msdn.microsoft.com/en-us/devlabs/ee794896.aspxMSDN forums – http://social.msdn.microsoft.com/Forums/en-US/rxChannel9 – http://channel9.msdn.com/Tags/Rx