Reactive Extensions(Rx)

 

Pavel Nasovich

Agenda

  • What is Rx?
  • Rx vs TPL
  • How to use Rx?
  • Demo time!
  • Where to go next?

What is Rx?

"Using Rx, developers represent asynchronous data streams with

- Rx README.md

+

+

=

What is Rx?

IEnumerable<T>

pull

foreach

IObservable<T>

push

Subscribe(IObserver)

T Current, bool MoveNext()

throws Exception

returns

OnNext(T)

OnError(Exception)

OnCompleted

What is Rx?

Rx vs TPL + DataFlow

Rx vs TPL + DataFlow

How to use Rx?

How to use Rx?

  • Unified Programming Model
  • Bridge into the Rx world:

Observable.FromEventPattern

Observable.FromAsync

Observer.Create

Observable.Create

  • Subject<T> is Observer and Observable (ReplaySubject, AsyncSubject, BehaviorSubject)

Demo

Examples

IDisposable subscription = Observable
    .FromEventPattern<EventHandler<TextChangedEventArgs>, TextChangedEventArgs>
(ah => textEditor.TextChanged += ah, rh => textEditor.TextChanged -= rh)
    .Throttle (TimeSpan.FromMilliseconds(400))
    .Select (query => query.EventArgs.NewTextValue.Trim())
    .Where (query => query.Length > 0)
    .ObserveOn(RxApp.MainThreadScheduler)
    .Do(q => listView.ItemsSource = null)
    .Do(q => loading.IsVisible = true)
    .Timeout(TimeSpan.FromSeconds(7))
    .Select (query => githubAPI.GetUserObservable (query))
    .Switch ()
    .Catch((Refit.ApiException e) => Observable.Return(new User()))
    .ObserveOn(RxApp.MainThreadScheduler)
    .Do(q => loading.ProgressTo(1,2, Easing.Linear))
    .Select (user => githubAPI.GetReposOwned(user.Login))
    .Switch ()
    .ObserveOn(RxApp.MainThreadScheduler)
    .Do(q => loading.ProgressTo(2,2, Easing.Linear))
    .Select (list => list.Where(repo => repo.Private != true))
    .Do(r => loading.IsVisible = false)
    .Retry()
    .Subscribe(
        onNext: list => listView.ItemsSource = list
    );

Please, don't repeat

Please, don't repeat

Please, don't repeat

Please, don't repeat

 What the hell is going on?

Exceptions

Don’t forget to handle the exceptions (the best way to do it is by using Catch()).

When in doubt

Do() is a really good tool for logging any observable that doesn’t behave the way you intended.

Memory leaks

Don’t forget to clean up after you subscribe to any observable (every Subscribe returns IDisposable).

Don’t stress

When learning how to write reactive code, you don’t need to write everything in a reactive way.

If you try to write reactive code that you don't feel comfortable with, it’s better to write it as you used to and come back to it when you have more experience.

Do your own extensions

Don’t be afraid to create your own extensions. It’s really simple to write for example a WhereIsNotNull(), which should be self-explanatory.

Testing

So how can you test an observable that should trigger every hour? With ease: just include into your test project the “Microsoft.Reactive.Testing” nuget package (from the same guys that develop Rx) and use the TestScheduler. It is a virtual time scheduler and makes you a Time Lord.

Where to go next?

Thank you!

Reactive Extensions for .net (Rx.NET)

By Pavel Nasovich

Reactive Extensions for .net (Rx.NET)

  • 1,319