Reactive Extensions

Why ?

Because our legacy apps are behaving like this.

 

Reactive extensions library is used for 

- composing events

- orchestrating data flows

- bring light to callback hell

Rx 

  • it's a library for .Net
  • also available in Java, Javascript, C++, Ruby, Python
  • used for building Reactive Applications

Message(Event) Driven

State

Let's try to be polite 

  • Don't call other modules functions
  • Publish events for communicating
  • Give others modules a chance to party

Rx contract

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

public interface IObserver<in T>
{
    void OnNext(T item);
    void OnCompleted();
    void OnError(Exception error);    
}

OnNext* (OnCompleted | OnError)?

Rx in .Net ecosystem

sync: 

async: 

One

Many

T

Task<T>

IObservable<T>

IEnumerable<T>

Observer pattern


    observable.Subscribe(observer);

Rx = 

Observables for representing asynchronous data streams

 

Linq for quering and transforming data

 

Schedulers for concurrency

 

Observables

Observables



Observable
    .Return("hello world")
    .Subscribe(message => Console.WriteLine(message));

Observables


Observable.Create<string>(observer => 
    {
        observer.OnNext("test1");
        observer.OnNext("test2");
        observer.OnCompleted();
        return Disposable.Empty;
    }).Subscribe(message => Console.WriteLine(message));

Observables



new int[] { 1, 2, 3 }
    .ToObservable()
    .Subscribe(number => Console.WriteLine(number));

SQL

SELECT name FROM students
SELECT name 
FROM students 
WHERE phoneNumber = "0722334455"

map : 

filter : 

Linq + Rx 

students
    .Select(student => student.Name)
    .Subscribe(name => Console.WriteLine(name))

map:

students
    .Where(student => 
        student.PhoneNumber == "0722334455")
    .Subscribe(student =>
        Console.WriteLine(student.Name))

filter:

  • query language over events
  • function composition
  • call functions by publishing events

New extensions for Rx 

  • Merge
  • CombineLatest
  • Throttle
  • Sample
  • Timeout
  • Delay
  • When, And, Then

Common used example

var textChanged = 
    from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged")
    select ((TextBox)evt.Sender).Text;

var input = textChanged
    .Throttle(TimeSpan.FromSeconds(1))
    .DistinctUntilChanged();

var webServiceClient = new HttpClient("http://..");
var searchOnWebService = Observable.FromAsync(webService.SearchAsync);

var results = from term in input
              from webResults in searchOnWebService.TakeUntil(input)
              select webResults 

Schedulers

  • Immediate
  • CurrentThread
  • NewThread
  • ThreadPool
  • TaskPool
  • TestScheduler
  • EventLoop

 SubscribeOn, ObserveOn

Observable.Create(observer => {
    printCurrentThread();
    observer.OnNext("hello"); })
.SubscribeOn(Schedulers.Immediate)
.ObserveOn(Schedulers.ThreadPool)
.Subscribe(message => {
    printCurrentThread();
    Console.WriteLine(message); });

Interested ?

Success stories

ReactiveExtensions

By gino

ReactiveExtensions

  • 610