reactive extensions: classic observer in .net

Post on 20-Jun-2015

234 Views

Category:

Software

5 Downloads

Preview:

Click to see full reader

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

Reactive Extensionsclassic observer in .NET

presenter: Sergiy Grytsenko

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

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>

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!

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

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

Why Rx?

Integrated

Unitive

Extensible

Declarative

Composable

Transformative

Why Rx?

Useful for

UI events

Domain events

Infrastructure events

Integration events

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

Key types & methods

IObservable<T>

IObserver<T>

Subjects

ObservableExtensions

Observable

Disposables

Key types & methodsDisposables BooleanDisposable

CancellationDisposable

CompositeDisposable

ContextDisposable

Disposable

MultipleAssignmentDisposable

RefCountDisposable

ScheduledDisposable

SerialDisposable

SingleAssignmentDisposable

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);}

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)

Key types & methodsSubjects

Subject.Create(observer, observable)

Subject<T>

AsyncSubject<T>

BehaviorSubject<T>

ReplaySubject<T>

Lifetime management & flow controlBuild your own pipe & valve system

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

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

Lifetime management & flow controlFlow control

OnError publishes exception, not thows

Subscribe w/o OnError handler causes exception to throw

Lifetime management & flow controlVisualization

Stream that publishes 3 values and then completes

Stream that publishes 4 values and then errors

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)

Lifetime management & flow controlConstructs

Materialize/Dematerialize

Do/Run

Combining several streamsSo many combinations…

Combining several streamsTransfer from one stream

Concat

Amb (short for Abmiguous)

Combining several streams Merge

SelectMany(other, selector)

Zip(other, selector)

Combining several streams

CombineLatest

ForkJoin

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

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)   {...}    }

Scheduling and Threading

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

Scheduling and Threading

Scheduler.Dispatcher

Scheduler.NewThread

Scheduler.ThreadPool

Scheduler.TaskPool

Scheduler.Immediate

Scheduler.CurrentThread

Tests, I need unit tests!Mastering time…

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.

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

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

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

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

top related