58
Rx: Curing your Asynchronous Programming Blues Bart J.F. De Smet Microso’ Corpora,on bartde@microso’.com

Rx: Curing Your Asynchronous Programming Blues | QCon London

Embed Size (px)

DESCRIPTION

At Microsofts Professional Developers Conference (PDC) a few years back, we introduced the LINQ project to solve the impedance mismatch between various data models by means of integrated query syntax in mainstream programming languages. Today, we’re seeing a rich ecosystem around LINQ providers that allow developers to reach out to many more data sources. However, there’s a lot of opportunity left to democratize even more data models. Based on the theory of monads, we’ll explore the incredibly powerful nature of query comprehensions to build reactive queries. Asynchronous, event-driven "reactive" programming is way too hard in today's world of development tools and frameworks. The huge amount of manual and error-prone plumbing leads to incomprehensible and hard to maintain code. As we reach out to services in the cloud, the desire for asynchronous computation is ever increasing, requiring a fresh look on the problems imposed by reactive programming. Centered around the concept of observable data sources, Rx provides a framework that takes care of the hard parts of reactive programming. Instead of focusing on the hard parts, you now can start dreaming about the endless possibilities of composing queries over asynchronous data sources, piggybacking on convenient LINQ syntax.In this session, we'll cover the design philosophy of Rx, rooted on the deep duality between the interactive IEnumerable interface and the new reactive IObservable interface in .NET 4.From this core understanding, we'll start looking at various combinators and operators defined over observable collections, as provided by Rx, driving concepts home by a bunch of samples. Finally, if time permits, we'll look at the Reactive Extensions for JavaScript which allows us to take the concepts we already know from Rx and apply them to JavaScript and have deep integration with libraries such as jQuery. Democratizing asynchronous programming starts today. Don't miss out on it!

Citation preview

Page 1: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Rx:  Curing  your  Asynchronous  Programming  Blues  

Bart  J.F.  De  Smet  Microso'  Corpora,on  bartde@microso'.com  

Page 2: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Why  Should  I  Care?  

Social  media  

Stock  ,ckers  

RSS            feeds  

GPS  

Server  management  

Page 3: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 4: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 5: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Essen,al  Interfaces  

You could get stuck

C# 4.0 covariance

(WaiHng  to  move  next)  

moving  on  

Page 6: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Mathema,cal  Duality  Because  the  Dutch  are  (said  to  be)  cheap  

– Electricity:    inductor  and  capacitor  

– Logic:    De  Morgan’s  Law  

– Programming?  

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

Page 7: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 8: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 9: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 10: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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#

Page 11: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

What’s  the  dual  of  IEnumerable?  

Page 12: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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 output too!

Page 13: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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”)  

Page 14: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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!

Page 15: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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!

Page 16: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 17: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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”)  

Page 18: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 19: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 20: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 21: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 22: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 23: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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?  

Page 24: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 25: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Essen,al  Interfaces  

Environment

MoveN

ext  

Got  next?  

ApplicaHon  

OnN

ext   Have  next!  

IEnumerable<T>  IEnumerator<T>  

IObservable<T>  IObserver<T>  

   

InteracHve  

ReacHve  

Page 26: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Demo  

Page 27: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Geeng  Your  Observables  

.Empty<int>()

.Return(42)

.Throw<int>(ex)

OnCompleted

OnNext

OnError

.Never<int>()

new  int[0]  

new[]  {  42  }  

Throwing  iterator  

Iterator  that  got  stuck  Notion of time

Page 28: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Geeng  Your  Observables  

OnNext OnError   OnCompleted  

.Range(0, 3)

OnNext(0) OnNext(1) OnNext(2)

.Range(0, 3)

yield 0 yield 1 yield 2

Page 29: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

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

new IEnumerable intfor int

yield  return  

foreach var inConsole

Hypothetical anonymous iterator syntax in C#

Synchronous Asynchronous

A variant with time notion exists (GenerateWithTime)

Geeng  Your  Observables  

Page 30: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 31: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 32: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 33: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 34: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 35: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Demo  

Page 36: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  World  

Hidden data source How to pass around?

Lack of composition

Resource maintenance?

Page 37: Rx: Curing Your Asynchronous Programming Blues |  QCon London
Page 38: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Source of Point values Objects can be passed

Can define operators

Resource maintenance!

Page 39: Rx: Curing Your Asynchronous Programming Blues |  QCon London

   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?

Page 40: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 41: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Bridging  Rx  with  the  World  

don’t  replace  

unifycomposiHonality  

generic operators  

build  bridges!  

Page 42: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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

Page 43: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Demo  

Page 44: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Composi,on  and  Querying  

IScheduler  var .Return Scheduler.ThreadPool

Console

Will run on the source’s scheduler

Parameterization of operators

Page 45: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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( )

Race!

Page 46: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Composi,on  and  Querying  

IScheduler interface •  WPF dispatcher •  WinForms control •  SynchronizationContext

synchronize.Return Scheduler.ThreadPool

"Answer  =  "

.ObserveOn(frm)       "Answer  =  "

Page 47: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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;  

Page 48: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Composi,on  and  Querying  

React TextChanged   Dictionary web service

Asynchronous request

Reaction Reactive Reactor

IObservable<string>

IObservable<DictionaryWord[]>

Data binding on UI thread

Page 49: Rx: Curing Your Asynchronous Programming Blues |  QCon London

//  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  

Page 50: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Demo  

Page 51: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 52: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 53: Rx: Curing Your Asynchronous Programming Blues |  QCon London

//  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  

Page 54: Rx: Curing Your Asynchronous Programming Blues |  QCon London

//  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  

Page 55: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Demo  

Page 56: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 57: Rx: Curing Your Asynchronous Programming Blues |  QCon London

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  

Page 58: Rx: Curing Your Asynchronous Programming Blues |  QCon London

Thanks!  Bart  J.F.  De  Smet