Reactive Extensions: classic Observer in .NET

36
Reactive Extensions classic observer in .NET presenter: Sergiy Grytsenko

description

Sergiy Grytsenko, Senior Software Engineer “Reactive Extensions: classic Observer in .NET” • Why should we use Rx when we have events? • Key types & methods • Lifetime management, flow control • Combining several streams • Tests, I need unit tests!

Transcript of Reactive Extensions: classic Observer in .NET

Page 1: Reactive Extensions: classic Observer in .NET

Reactive Extensionsclassic observer in .NET

presenter: Sergiy Grytsenko

Page 2: Reactive Extensions: classic Observer in .NET

About presenter

Senior Developer @ EPAM Systems

17 years of programing with Basic, Pascal, Assembler, C/C++, C#

12 years of professional development

Developed several projects using Rx

Page 3: Reactive Extensions: classic Observer in .NET

Target auditory

UI developers that deals with asynchronous code/want responsive UI

Back-end developers that wish to make server async and responsive

You just curious about the IObservable<T> and IObserver<T>

Page 4: Reactive Extensions: classic Observer in .NET

Agenda

Why use Rx when we have events?

Key types & methods

Lifetime management & flow control

Combining several streams

Scheduling and Threading

Tests, I need unit tests!

Page 5: Reactive Extensions: classic Observer in .NET

Why use Rx when we have events?“To be or not to be” ©

Page 6: Reactive Extensions: classic Observer in .NET

Why Rx?

You demand fire-and-forget messaging

You want to have the result pushed to you when it is ready

You do not want wait for entire set to be processed before you see first one

Developers have tools to push data

Developers need tools to react to push data

Rx enables developers to solve problems in an elegant, familiar and declarative style with less code

It is easily to manage events and subscriptions

Page 7: Reactive Extensions: classic Observer in .NET

Why Rx?

Integrated

Unitive

Extensible

Declarative

Composable

Transformative

Page 8: Reactive Extensions: classic Observer in .NET

Why Rx?

Useful for

UI events

Domain events

Infrastructure events

Integration events

Page 9: Reactive Extensions: classic Observer in .NET

Key types & methodsThe key to the door that you want to open

Page 10: Reactive Extensions: classic Observer in .NET

Key types & methods

IObservable<T>

IObserver<T>

Subjects

ObservableExtensions

Observable

Disposables

Page 11: Reactive Extensions: classic Observer in .NET

Key types & methodsDisposables BooleanDisposable

CancellationDisposable

CompositeDisposable

ContextDisposable

Disposable

MultipleAssignmentDisposable

RefCountDisposable

ScheduledDisposable

SerialDisposable

SingleAssignmentDisposable

Page 12: Reactive Extensions: classic Observer in .NET

Key types & methodsSubscription overrides

public static class ObservableExtensions{ public static IDisposable Subscribe<T>(this IObservable<T> source); public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext); public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError); public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted); public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted); public static void Subscribe<T>(this IObservable<T> source, IObserver<T> observer, CancellationToken token); public static void Subscribe<T>(this IObservable<T> source, CancellationToken token); public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, CancellationToken token); public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, CancellationToken token); public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted, CancellationToken token); public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted, CancellationToken token); public static IDisposable SubscribeSafe<T>(this IObservable<T> source, IObserver<T> observer);}

Page 13: Reactive Extensions: classic Observer in .NET

Key types & methodsCreating observables

Observable.Empty<T>()

Observable.Return<T>(T)

Observable.Never<T>()

Observable.Throw<T>(Exception)

Observable.Create<T>(Func<IObserver<T>, IDisposable>)

IObservable<int> Observable.Range(int, int)

IObservalbe<long> Observable.Interval(TimeSpan);

Observable.Start<T/Unit>(Func<T>/Action)

ToObservable<T>(IEnumerable<T>)

Observalble.Generate(initialState, condition, iterate, resultSelector)

Page 14: Reactive Extensions: classic Observer in .NET

Key types & methodsSubjects

Subject.Create(observer, observable)

Subject<T>

AsyncSubject<T>

BehaviorSubject<T>

ReplaySubject<T>

Page 15: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlBuild your own pipe & valve system

Page 16: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlSubscription lifetime

There is many Subscribe overloads but no Unsubscribe method

Rx returns IDisposable whenever subscription takes place

Or you can provide CancellationToken to unsubscribe

Think of IDisposable as subscription token

You can call Subscribe many times on single IObservable

Page 17: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlObservable lifetime

Both OnError & OnCompleted signify the completion of a stream

No futher calls to OnNext can be performed

When stream completes or errors, you should still dispose subscription

Page 18: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlFlow control

OnError publishes exception, not thows

Subscribe w/o OnError handler causes exception to throw

Page 19: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlVisualization

Stream that publishes 3 values and then completes

Stream that publishes 4 values and then errors

Page 20: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlConstructs

Retry<T>(this IObservable<T> source)

OnErrorResumeNext<T>(this IObservable<T> source, IObservable<T> next)

Catch(this IObservable<T> source, Func<TException, IObservalbe<T>> next)

Page 21: Reactive Extensions: classic Observer in .NET

Lifetime management & flow controlConstructs

Materialize/Dematerialize

Do/Run

Page 22: Reactive Extensions: classic Observer in .NET

Combining several streamsSo many combinations…

Page 23: Reactive Extensions: classic Observer in .NET

Combining several streamsTransfer from one stream

Concat

Amb (short for Abmiguous)

Page 24: Reactive Extensions: classic Observer in .NET

Combining several streams Merge

SelectMany(other, selector)

Zip(other, selector)

Page 25: Reactive Extensions: classic Observer in .NET

Combining several streams

CombineLatest

ForkJoin

Page 26: Reactive Extensions: classic Observer in .NET

Scheduling and Threadingeffectively remove the need for WaitHandles, and any explicit calls to using Threads, the ThreadPool and the new shiny Task type

Page 27: Reactive Extensions: classic Observer in .NET

Scheduling and Threading

The invocation of the subscription

The publishing of notifications

    public static class Observable    {        public static IObservable<TSource> ObserveOn<TSource>(            this IObservable<TSource> source, IScheduler scheduler)   {...}        public static IObservable<TSource> SubscribeOn<TSource>(              this IObservable<TSource> source, IScheduler scheduler)   {...}    }

Page 28: Reactive Extensions: classic Observer in .NET

Scheduling and Threading

public interface IScheduler{    IDisposable Schedule(Action action);    IDisposable Schedule(Action action, TimeSpan dueTime);    DateTimeOffset Now { get; }}    

Page 29: Reactive Extensions: classic Observer in .NET

Scheduling and Threading

Scheduler.Dispatcher

Scheduler.NewThread

Scheduler.ThreadPool

Scheduler.TaskPool

Scheduler.Immediate

Scheduler.CurrentThread

Page 30: Reactive Extensions: classic Observer in .NET

Tests, I need unit tests!Mastering time…

Page 31: Reactive Extensions: classic Observer in .NET

Tests, I need unit tests!

Scheduling and therefore Threading are generally avoided in test scenarios as they can introduce race conditions which may lead to non-deterministic tests.

Tests should run as fast as possible.

Rx is a new technology/library so naturally as we master it, we will refactor our code. We want to use to tests to ensure our refactoring have not altered the internal behavior of our code base.

Page 32: Reactive Extensions: classic Observer in .NET

Tests, I need unit tests!TestScheduler

A virtual scheduler to allow us emulate and control time.var scheduler = new TestScheduler();var wasExecuted = false;scheduler.Schedule(() => wasExecuted = true);Assert.IsFalse(wasExecuted);scheduler.AdvanceTo(1);         //execute 1 tick of queued actionsAssert.IsTrue(wasExecuted);

Page 33: Reactive Extensions: classic Observer in .NET

Tests, I need unit tests!TestSchedulervar scheduler = new TestScheduler();var dueTime = TimeSpan.FromMilliseconds(400);var delta = TimeSpan.FromMilliseconds(100);scheduler.Schedule(dueTime, () => Console.WriteLine("1"));scheduler.Schedule(dueTime, () => Console.WriteLine("2"));scheduler.Schedule(dueTime.Add(delta), () => Console.WriteLine("3"));scheduler.Schedule(dueTime.Add(delta), () => Console.WriteLine("4"));Console.WriteLine("RunTo(dueTime)");scheduler.AdvanceTo(dueTime.Ticks);Console.WriteLine("Run()");scheduler.Start();/* Output:            RunTo(dueTime)            1            2            Run()            3            4            */

Page 34: Reactive Extensions: classic Observer in .NET

Useful links

IObservable<T> interface – MSDN

IObserver<T> interface – MSDN

Observer Design pattern - MSDN 

Rx Home http://msdn.microsoft.com/en-us/devlabs/gg577609 

Exploring the Major Interfaces in Rx – MSDN 

ObservableExtensions class - MSDN

Using Rx Subjects - MSDN

System.Reactive.Subjects Namespace - MSDN

Subject<T> - MSDN

AsyncSubject<T> - MSDN

BehaviorSubject<T> - MSDN

ReplaySubject<T> - MSDN

Subject static class - MSDN

ISubject<TSource, TResult> - MSDN

ISubject<T> - MSDN

Page 35: Reactive Extensions: classic Observer in .NET

Useful links

Observable class - MSDN

Observer class - MSDN

Qservable class - MSDN 

The Rx Wiki site 101 Samples http://rxwiki.wikidot.com/101samples

http://channel9.msdn.com/shows/Going+Deep/Wes-Dyer-and-Jeffrey-Van-Gogh-Inside-Rx-Virtual-Time/

http://channel9.msdn.com/posts/J.Van.Gogh/Rx-API-in-depth-Hot-and-Cold-observables/

http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/03/13/rx-for-beginners-part-9-hot-vs-cold-observable.aspx