Reactive Extensions: classic Observer in .NET
-
Upload
epam-systems -
Category
Software
-
view
228 -
download
5
description
Transcript of Reactive Extensions: classic Observer in .NET
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
Useful links
http://channel9.msdn.com/Shows/Going+Deep/Bart-De-Smet-MinLINQ-The-Essence-of-LINQ
http://leecampbell.blogspot.com/2010/08/reactive-extensions-for-net.html
http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-August-17-2012
http://channel9.msdn.com/Series/Rx-Workshop
http://channel9.msdn.com/Blogs/J.Van.Gogh
http://channel9.msdn.com/Blogs/Charles/Erik-Meijer-Rx-in-15-Minutes
http://channel9.msdn.com/Blogs/Peli/Testing-Rx-with-Pex