Rx: Curing your Asynchronous Programming Blues Bart J.F. - - PowerPoint PPT Presentation

rx curing your asynchronous programming blues
SMART_READER_LITE
LIVE PREVIEW

Rx: Curing your Asynchronous Programming Blues Bart J.F. - - PowerPoint PPT Presentation

Rx: Curing your Asynchronous Programming Blues Bart J.F. De Smet Microso' Corpora,on bartde@microso'.com Why Should I Care? GPS RSS


slide-1
SLIDE 1

Rx: ¡Curing ¡your ¡Asynchronous ¡ Programming ¡Blues ¡

Bart ¡J.F. ¡De ¡Smet ¡

Microso' ¡Corpora,on ¡ bartde@microso'.com ¡

slide-2
SLIDE 2

Why ¡Should ¡I ¡Care? ¡

Social ¡ media ¡ Stock ¡,ckers ¡ RSS ¡ ¡ ¡ ¡ ¡ ¡feeds ¡ GPS ¡ Server ¡management ¡

slide-3
SLIDE 3

Mission ¡Statement ¡

Rx is a library for composing asynchronous and event-based programs using observable sequences.

(! ¡◦ ¡")(#) ¡= ¡!("(#))

Queries? ¡LINQ? ¡ Too ¡hard ¡today! ¡

  • .NET ¡3.5 ¡SP1 ¡and ¡4.0 ¡
  • Silverlight ¡3 ¡and ¡4 ¡
  • XNA ¡3.1 ¡for ¡XBOX ¡and ¡Zune ¡
  • Windows ¡Phone ¡7 ¡
  • JavaScript ¡(RxJS) ¡

MSDN ¡Data ¡Developer ¡Center ¡ NuGet ¡

slide-4
SLIDE 4

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

Essen,al ¡Interfaces ¡

You could get stuck C# 4.0 covariance

slide-5
SLIDE 5

Essen,al ¡Interfaces ¡

You could get stuck C# 4.0 covariance

(WaiHng ¡to ¡move ¡next) ¡ moving ¡on ¡

slide-6
SLIDE 6

Mathema,cal ¡Duality ¡

Because ¡the ¡Dutch ¡are ¡(said ¡to ¡be) ¡cheap ¡

– Electricity: ¡ ¡inductor ¡and ¡capacitor ¡ – Logic: ¡ ¡De ¡Morgan’s ¡Law ¡ – Programming? ¡

¬(%∧&)≡¬%∨¬& ¡

¡

¬(%∨&)≡¬%∧¬& ¡

¡

slide-7
SLIDE 7

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

The ¡recipe ¡to ¡dualiza,on ¡

h^p://en.wikipedia.org/wiki/Dual_(category_theory)

Reversing arrows… Input becomes output and vice versa

Making ¡a ¡U-­‑turn ¡ in ¡synchrony ¡

slide-8
SLIDE 8

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

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Properties are methods

slide-9
SLIDE 9

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡bool ¡ ¡MoveNext(); ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ ¡ ¡void ¡ ¡Reset(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

A historical mishap

slide-10
SLIDE 10

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡bool ¡ ¡MoveNext(); ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

No checked exceptions in .NET / C#

slide-11
SLIDE 11

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡bool ¡ ¡MoveNext() ¡throws ¡Exception; ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

slide-12
SLIDE 12

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡bool ¡ ¡MoveNext() ¡throws ¡Exception; ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

This is an

  • utput too!
slide-13
SLIDE 13

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡(bool ¡| ¡Exception) ¡MoveNext(); ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Really only two values

Discriminated ¡union ¡ type ¡(“or”) ¡

slide-14
SLIDE 14

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡(true ¡| ¡false ¡| ¡Exception) ¡MoveNext(); ¡ ¡ ¡T ¡ ¡ ¡ ¡ ¡GetCurrent(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Got true? Really got T!

slide-15
SLIDE 15

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡(T ¡| ¡false ¡| ¡Exception) ¡MoveNext(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Got false? Really got void!

slide-16
SLIDE 16

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡IEnumerator<T> ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡: ¡IDisposable ¡ { ¡ ¡ ¡(T ¡| ¡void ¡| ¡Exception) ¡MoveNext(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Every enumerator is disposable

slide-17
SLIDE 17

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡(IEnumerator<T> ¡& ¡IDisposable) ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡ { ¡ ¡ ¡(T ¡| ¡void ¡| ¡Exception) ¡MoveNext(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Hypothe4cal ¡syntax ¡(“and”) ¡

slide-18
SLIDE 18

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡(IEnumerator<T> ¡& ¡IDisposable) ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumerator<out ¡T> ¡ { ¡ ¡ ¡(T ¡| ¡void ¡| ¡Exception) ¡MoveNext(); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

This is really void Variance will flip! Will rename too

slide-19
SLIDE 19

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡(IEnumerator<T> ¡& ¡IDisposable) ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumeratorDual<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡| ¡void ¡| ¡Exception); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Can encode as three methods

slide-20
SLIDE 20

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡(IEnumerator<T> ¡& ¡IDisposable) ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IEnumeratorDual<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡value); ¡ ¡ ¡void ¡ ¡ ¡OnCompleted(); ¡ ¡ ¡void ¡ ¡ ¡OnError(Exception ¡exception); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Color of the bikeshed (*)

(*) ¡Visit ¡h^p://en.wikipedia.org/wiki/Color_of_the_bikeshed ¡

slide-21
SLIDE 21

interface ¡IEnumerable<out ¡T> ¡ { ¡ ¡ ¡(IEnumerator<T> ¡& ¡IDisposable) ¡GetEnumerator(); ¡ } ¡ ¡ interface ¡IObserver<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡value); ¡ ¡ ¡void ¡ ¡ ¡OnCompleted(); ¡ ¡ ¡void ¡ ¡ ¡OnError(Exception ¡exception); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Need to patch this one up too Will leave this part alone This is the data source

slide-22
SLIDE 22

interface ¡IEnumerableDual<out ¡T> ¡ { ¡ ¡ ¡IDisposable ¡SetObserver(IObserver<T> ¡observer); ¡ } ¡ ¡ interface ¡IObserver<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡value); ¡ ¡ ¡void ¡ ¡ ¡OnCompleted(); ¡ ¡ ¡void ¡ ¡ ¡OnError(Exception ¡exception); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

Color of the bikeshed (*)

(*) ¡Visit ¡h^p://en.wikipedia.org/wiki/Color_of_the_bikeshed ¡

slide-23
SLIDE 23

interface ¡IObservable<out ¡T> ¡ { ¡ ¡ ¡IDisposable ¡Subscribe(IObserver<T> ¡observer); ¡ } ¡ ¡ interface ¡IObserver<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡value); ¡ ¡ ¡void ¡ ¡ ¡OnCompleted(); ¡ ¡ ¡void ¡ ¡ ¡OnError(Exception ¡exception); ¡ } ¡

What’s ¡the ¡dual ¡of ¡IEnumerable? ¡

slide-24
SLIDE 24

interface ¡IObservable<out ¡T> ¡ { ¡ ¡ ¡IDisposable ¡Subscribe(IObserver<T> ¡observer); ¡ } ¡ ¡ interface ¡IObserver<in ¡T> ¡ { ¡ ¡ ¡void ¡ ¡ ¡OnNext(T ¡value); ¡ ¡ ¡void ¡ ¡ ¡OnError(Exception ¡ex); ¡ ¡ ¡void ¡ ¡ ¡OnCompleted(); ¡ } ¡

Essen,al ¡Interfaces ¡

You could get flooded C# 4.0 contravariance

slide-25
SLIDE 25

Essen,al ¡Interfaces ¡

Environment

MoveNext ¡ Got ¡next? ¡

ApplicaHon ¡

OnNext ¡ Have ¡next! ¡ IEnumerable<T> ¡ IEnumerator<T> ¡ IObservable<T> ¡ IObserver<T> ¡ ¡ ¡

InteracHve ¡ ReacHve ¡

slide-26
SLIDE 26

Demo ¡

slide-27
SLIDE 27

Geeng ¡Your ¡Observables ¡

.Empty Empty<int int>() >() .Return Return(42) (42) .Throw Throw<int int>(ex) >(ex) OnCompleted OnNext OnError .Never Never<int int>() >() new ¡int[0] ¡ new[] ¡{ ¡42 ¡} ¡ Throwing ¡iterator ¡ Iterator ¡that ¡got ¡stuck ¡ Notion of time

slide-28
SLIDE 28

Geeng ¡Your ¡Observables ¡

OnNext OnError ¡ OnCompleted ¡

.Range Range(0, 3) (0, 3) OnNext(0) OnNext(1) OnNext(2) .Range Range(0, 3) (0, 3) yield 0 yield 1 yield 2

slide-29
SLIDE 29
  • ¡= ¡Observable.Generate( ¡

¡ ¡ ¡0, ¡ ¡ ¡ ¡i ¡=> ¡i ¡< ¡10, ¡ ¡ ¡ ¡i ¡=> ¡i ¡+ ¡1, ¡ ¡ ¡ ¡i ¡=> ¡i ¡* ¡i ¡ ); ¡

  • .Subscribe(x ¡=> ¡{ ¡

¡ ¡ ¡Console.WriteLine(x); ¡ }); ¡ new IEnumerable int for int yield ¡return ¡ foreach var in Console Hypothetical anonymous iterator syntax in C# Synchronous Asynchronou s A variant with time notion exists (GenerateWithTime)

Geeng ¡Your ¡Observables ¡

slide-30
SLIDE 30

IObservable<int> ¡o ¡= ¡Observable.Create<int>(observer ¡=> ¡{ ¡ ¡ ¡// ¡Assume ¡we ¡introduce ¡concurrency ¡(see ¡later)… ¡ ¡ ¡observer.OnNext(42); ¡ ¡ ¡observer.OnCompleted(); ¡ ¡ ¡return ¡() ¡=> ¡{ ¡/* ¡unsubscribe ¡action ¡*/ ¡}; ¡ }); ¡ IDisposable ¡subscription ¡= ¡o.Subscribe( ¡ ¡ ¡onNext: ¡ ¡ ¡ ¡ ¡ ¡x ¡ ¡=> ¡{ ¡Console.WriteLine("Next: ¡" ¡+ ¡x); ¡}, ¡ ¡ ¡onError: ¡ ¡ ¡ ¡ ¡ex ¡=> ¡{ ¡Console.WriteLine("Oops: ¡" ¡+ ¡ex); ¡}, ¡ ¡ ¡onCompleted: ¡() ¡=> ¡{ ¡Console.WriteLine("Done"); ¡} ¡ ); ¡ C# doesn’t have anonymous interface implementation, so we provide various extension methods that take lambdas. C# 4.0 named parameter syntax

Geeng ¡Your ¡Observables ¡

slide-31
SLIDE 31

IObservable<int> ¡o ¡= ¡Observable.Create<int>(observer ¡=> ¡{ ¡ ¡ ¡// ¡Assume ¡we ¡introduce ¡concurrency ¡(see ¡later)… ¡ ¡ ¡observer.OnNext(42); ¡ ¡ ¡observer.OnCompleted(); ¡ ¡ ¡return ¡() ¡=> ¡{ ¡/* ¡unsubscribe ¡action ¡*/ ¡}; ¡ }); ¡ 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… ¡

F10

Geeng ¡Your ¡Observables ¡

slide-32
SLIDE 32

IObservable<int> ¡o ¡= ¡Observable.Create<int>(observer ¡=> ¡{ ¡ ¡ ¡// ¡Assume ¡we ¡introduce ¡concurrency ¡(see ¡later)… ¡ ¡ ¡observer.OnNext(42); ¡ ¡ ¡observer.OnCompleted(); ¡ ¡ ¡return ¡() ¡=> ¡{ ¡/* ¡unsubscribe ¡action ¡*/ ¡}; ¡ }); ¡ 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… ¡

F10

Geeng ¡Your ¡Observables ¡

slide-33
SLIDE 33

IObservable<int> ¡o ¡= ¡Observable.Create<int>(observer ¡=> ¡{ ¡ ¡ ¡// ¡Assume ¡we ¡introduce ¡concurrency ¡(see ¡later)… ¡ ¡ ¡observer.OnNext(42); ¡ ¡ ¡observer.OnCompleted(); ¡ ¡ ¡return ¡() ¡=> ¡{ ¡/* ¡unsubscribe ¡action ¡*/ ¡}; ¡ }); ¡ 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… ¡

F5

Geeng ¡Your ¡Observables ¡

slide-34
SLIDE 34

IObservable<int> ¡o ¡= ¡Observable.Create<int>(observer ¡=> ¡{ ¡ ¡ ¡// ¡Assume ¡we ¡introduce ¡concurrency ¡(see ¡later)… ¡ ¡ ¡observer.OnNext(42); ¡ ¡ ¡observer.OnCompleted(); ¡ ¡ ¡return ¡() ¡=> ¡{ ¡/* ¡unsubscribe ¡action ¡*/ ¡}; ¡ }); ¡ 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… ¡ Breakpoint got hit

Geeng ¡Your ¡Observables ¡

slide-35
SLIDE 35

Demo ¡

slide-36
SLIDE 36

form1.MouseMove .MouseMove += (sender, args args) => { if (args.Location.X == args.Location.Y) ) // I’d like to raise another event }; form1.MouseMove -=

  • = /* what goes here? */

Bridging ¡Rx ¡with ¡the ¡World ¡

Hidden data source How to pass around? Lack of composition Resource maintenance?

slide-37
SLIDE 37
slide-38
SLIDE 38

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

Bridging ¡Rx ¡with ¡the ¡World ¡

Source of Point values Objects can be passed Can define operators Resource maintenance!

slide-39
SLIDE 39

¡ ¡ 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 ¡World ¡

Hidden data source Really a method pair Lack of composition Exceptions? Synchronous completion? Cancel? State?

slide-40
SLIDE 40

Bridging ¡Rx ¡with ¡the ¡World ¡

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

slide-41
SLIDE 41

Bridging ¡Rx ¡with ¡the ¡World ¡

don’t ¡replace ¡

unify composiHonality ¡ generic operators ¡ build ¡bridges! ¡

slide-42
SLIDE 42

Bridging ¡Rx ¡with ¡the ¡World ¡

  • Cold ¡observables ¡

¡ ¡

  • Hot ¡observables ¡

var ¡ Observable.Return .Subscribe( ) // ¡Prints ¡42 ¡ .Subscribe( ) // ¡Prints ¡42 ¡again ¡ Triggered by subscription var Observable.FromEvent MouseEventArgs "MouseMove" Console Mouse events going before subscription

slide-43
SLIDE 43

Demo ¡

slide-44
SLIDE 44

Composi,on ¡and ¡Querying ¡

IScheduler ¡

var .Return Scheduler.ThreadPool Console Will run on the source’s scheduler Parameterization

  • f operators
slide-45
SLIDE 45

Composi,on ¡and ¡Querying ¡

duality

– Convert ¡between ¡both ¡worlds ¡

  • “Time-­‑centric” ¡reacHve ¡operators: ¡

// ¡Introduces ¡concurrency ¡to ¡enumerate ¡and ¡signal… ¡ var .ToObservable(); ¡ // ¡Removes ¡concurrency ¡by ¡observing ¡and ¡yielding… ¡ var .ToEnumerable() .Amb( .Amb( ) ) Race!

slide-46
SLIDE 46

Composi,on ¡and ¡Querying ¡

IScheduler interface

  • WPF dispatcher
  • WinForms control
  • SynchronizationContext

synchronize

.Return Scheduler.ThreadPool "Answer ¡= ¡" .ObserveOn(frm) ¡ ¡ ¡ "Answer ¡= ¡"

slide-47
SLIDE 47

Composi,on ¡and ¡Querying ¡

  • Observables ¡are ¡sources ¡of ¡data ¡

– Data ¡is ¡sent ¡to ¡you ¡(push ¡based) ¡ – Extra ¡(op,onal) ¡noHon ¡of ¡Hme ¡

  • Hence ¡we ¡can ¡query ¡over ¡them ¡

// ¡Producing ¡an ¡IObservable<Point> ¡using ¡Select ¡ var ¡mme ¡= ¡from ¡mm ¡in ¡Observable.FromEvent<MouseEventArgs>( ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡form, ¡“MouseMove”) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡select ¡mm.EventArgs.Location; ¡ ¡ // ¡Filtering ¡for ¡the ¡first ¡bisector ¡using ¡Where ¡ var ¡res ¡= ¡from ¡mm ¡in ¡mme ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡where ¡mm.X ¡== ¡mm.Y ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡select ¡mm; ¡

slide-48
SLIDE 48

Composi,on ¡and ¡Querying ¡

React TextChanged ¡

Dictionary web service Asynchronou s request

Reaction Reactive Reactor

IObservable<string> IObservable<DictionaryWord[]> Data binding

  • n UI thread
slide-49
SLIDE 49

// ¡IObservable<string> ¡from ¡TextChanged ¡events ¡ var ¡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 ¡service ¡ var ¡svc ¡= ¡new ¡DictServiceSoapClient(); ¡ var ¡lookup ¡= ¡Observable.FromAsyncPattern<string, ¡DictionaryWord[]> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(svc.BeginLookup, ¡svc.EndLookup); ¡ // ¡Compose ¡both ¡sources ¡using ¡SelectMany ¡ var ¡res ¡= ¡from ¡term ¡in ¡input ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡from ¡words ¡in ¡lookup(term) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡select ¡words; ¡ input.SelectMany(term ¡=> ¡ lookup(term)) ¡

Composi,on ¡and ¡Querying ¡

slide-50
SLIDE 50

Demo ¡

slide-51
SLIDE 51

input input Service ¡call ¡1 ¡ Service ¡call ¡2 ¡ UI ¡data ¡binding ¡ | R| Re| Rea| Reac| React| React| Reacti| Reactiv| Reactive| Reactive Reaction Reactive Reactor

Source: http://scrapetv.com

Composi,on ¡and ¡Querying ¡

slide-52
SLIDE 52

input input Service ¡call ¡1 ¡ Service ¡call ¡2 ¡ UI ¡data ¡binding ¡ | R| Re| Rea| Reac| React| React| Reacti| Reactiv| Reactive| Reactive Take ¡ UnHl ¡

Composi,on ¡and ¡Querying ¡

slide-53
SLIDE 53

// ¡IObservable<string> ¡from ¡TextChanged ¡events ¡ var ¡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 ¡service ¡ var ¡svc ¡= ¡new ¡DictServiceSoapClient(); ¡ var ¡lookup ¡= ¡Observable.FromAsyncPattern<string, ¡DictionaryWord[]> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(svc.BeginLookup, ¡svc.EndLookup); ¡ // ¡Compose ¡both ¡sources ¡using ¡SelectMany ¡ var ¡res ¡= ¡from ¡term ¡in ¡input ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡from ¡words ¡in ¡lookup(term).TakeUntil(input) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡select ¡words; ¡

Very local fix J

Composi,on ¡and ¡Querying ¡

slide-54
SLIDE 54

// ¡IObservable<string> ¡from ¡TextChanged ¡events ¡ var ¡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 ¡service ¡ var ¡svc ¡= ¡new ¡DictServiceSoapClient(); ¡ var ¡lookup ¡= ¡Observable.FromAsyncPattern<string, ¡DictionaryWord[]> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(svc.BeginLookup, ¡svc.EndLookup); ¡ // ¡Alternative ¡approach ¡for ¡composition ¡using: ¡ // ¡ ¡ ¡IObservable<T> ¡Switch<T>(IObservable<IObservable<T>> ¡sources) ¡ var ¡res ¡= ¡(from ¡term ¡in ¡input ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡select ¡lookup(term)).Switch(); ¡

Hops from source to source

Composi,on ¡and ¡Querying ¡

slide-55
SLIDE 55

Demo ¡

slide-56
SLIDE 56

Mission ¡Accomplished ¡

Rx is a library for composing asynchronous and event-based programs using observable sequences.

(! ¡◦ ¡")(#) ¡= ¡!("(#))

Queries! ¡LINQ! ¡ Way ¡simpler ¡with ¡Rx ¡

  • .NET ¡3.5 ¡SP1 ¡and ¡4.0 ¡
  • Silverlight ¡3 ¡and ¡4 ¡
  • XNA ¡3.1 ¡for ¡XBOX ¡and ¡Zune ¡
  • Windows ¡Phone ¡7 ¡
  • JavaScript ¡(RxJS) ¡

MSDN ¡Data ¡Developer ¡Center ¡ NuGet ¡

slide-57
SLIDE 57

Related ¡Content ¡

  • Hands-­‑on ¡Labs ¡

– Two ¡flavors: ¡

  • Curing ¡the ¡asynchronous ¡blues ¡with ¡the ¡Reac,ve ¡Extensions ¡(Rx) ¡for ¡.NET ¡
  • Curing ¡the ¡asynchronous ¡blues ¡with ¡the ¡Reac,ve ¡Extensions ¡(Rx) ¡for ¡JavaScript ¡

– Both ¡can ¡be ¡found ¡via ¡the ¡Rx ¡forums ¡

  • Rx ¡team ¡web ¡presence ¡

– Rx ¡team ¡blog ¡– ¡h^p://blogs.msdn.com/rxteam ¡ – DevLabs ¡– ¡h^p://msdn.microso'.com/en-­‑us/devlabs/ee794896.aspx ¡ – MSDN ¡forums ¡– ¡h^p://social.msdn.microso'.com/Forums/en-­‑US/rx ¡ – Channel9 ¡– ¡h^p://channel9.msdn.com/Tags/Rx ¡

slide-58
SLIDE 58

Thanks! ¡

Bart ¡J.F. ¡De ¡Smet ¡