Rx Frameworkblog.jayway.com/wp-content/uploads/2010/05/Rx.pdfo System.Observable.dll (.NET 3.5) o...
Transcript of Rx Frameworkblog.jayway.com/wp-content/uploads/2010/05/Rx.pdfo System.Observable.dll (.NET 3.5) o...
Rx Framework
Mattias Sjögren
Rx Framework
Reactive Extensions for .NET
Volta
Rx Framework
“It's […] the culmination of one the most significant discoveries about
the fundamental nature of asynchronous programming.”
- Jafar Husain, MS Silverlight Team
“Using Rx, programmers can write succinct declarative code to
orchestrate and coordinate asynchronous and event-based
programs based on familiar .NET idioms and patterns. [...] By
combining the expressiveness of LINQ with the elegance of
category theory, Rx allows programmers to write asynchronous code
without performing cruel and unnatural acts.”
- S. Somasegar, Senior VP, MS Developer Division
Reactive vs Interactive
Environment
Programo Callbacks
o Events
o Notifications
o Method calls
o Iterators
o Enumerations
Enumerations
o IEnumerable & IEnumerator in .NET 1.0
o foreach in C# 1.0 (For Each in VB.NET)
o Generic collections in .NET 2.0
o Easier to implement with C# 2.0 Iterators
o Empowered by LINQ in .NET 3.5
o GoF Iterator pattern
Observables
o .NET 1.0o Delegates & Events
o Callback interfaces
o Asynchronous Programming Model (APM)
o .NET 2.0 - 3.5o INotifyPropertyChanged
o ObservableCollection<T> & INotifyCollectionChanged
o C# anonymous delegates & lambdas
o .NET 4.0o Task Parallell Library (TPL) Task
o Finally a common interface: IObservable<T>
o GoF Observer pattern
Duality
IEnumerator<out T>
T Current { get; }
bool MoveNext();
void Reset();
void Dispose();
IObserver<in T>
void OnNext(T value);
void OnCompleted();
void OnError(Exception error);
IEnumerable<out T>
IEnumerator<T> GetEnumerator();
IObservable<out T>
IDisposable Subscribe(
IObserver<T> observer);
4 Editions
o Rx for .NET Framework 3.5 SP1
o Rx for .NET Framework 4.0
o Rx for Silverlight 3
o Rx for JavaScript
What’s in the Framework?
o System.Observable.dll (.NET 3.5)o IObservable<T> and IObserver<T>
o System.Threading.dll (.NET 3.5)o Back-port of Parallell Extensions
o System.Reactive.dllo For working with Observables
o System.Interactive.dllo For working with Enumerables
o System.CoreEx.dllo Shared types, Scheduling, IEvent<T>
Subscribingo Implementing IObserver<T> is cumbersome but often
unneccessary
o Extension methods let us pass in handlers for OnNext,
OnCompleted and/or OnError
o Call Dispose on returned object to unsubscribe
class MyObserver<T> : IObserver<T>{
public void OnNext(T value) { ProcessMessage(value); }public void OnCompleted() { HandleCompleted(); }public void OnError(Exception ex) { HandleException(ex); }
}
//IDisposable IObservable<T>.Subscribe(IObserver<T> observer);observable.Subscribe(new MyObserver<T>());
observable.Subscribe(onNext: msg => ProcessMessage(msg),onError: ex => HandleError(ex),onCompleted: () => HandleCompleted() );
System.Linq.ObservablePrimitives
Never
Empty
Return
Throw
Creation
Defer
Range
Repeat
Generate
Combine
Amb
Concat
StartWith
Merge
Repeat
Zip
Convert
ToObservable
ToEnumerable
FromAsyncPattern
FromEvent
Exceptions
Catch
Finally
RetryOnErrorResumeNext
Selection
Take
TakeUntil/While
Select
SelectMany
Skip
SkipUntil/While
Time
Delay
Interval
TimeInterval
Timestamp
Timeout
Math
Aggregate
Count
Min
Max
Sum
Functional
Let
Prune
Publish
Replay
Misc
Do
Run
Remotable
Marble Diagrams
Graphical representation of observable operations.
WhereIObservable<int> source = Observable.Range(1, 5);
IObservable<int> result = source.Where(i => i % 2 == 0);
IO<int> source
IO<int> result
predicate: i % 2 == 0
Operators: Primitives
Never
Empty
Return
Throw
Operators: Repeat
IObservable<T> Repeat(this IObservable<T> source, int repeatCount);
IO<T> source
IO<T> result
IO<T> source
Operators: Merge
IObservable<T> Merge(this IObservable<T> first, IObservable<T> second);
IO<T> first
IO<T> result
IO<T> second
Operators: Zip
IObservable<V> Zip(this IObservable<T> first,
IObservable<U> second,
Func<T, U, V> selector);
IO<T> first
IO<V> result
IO<U> second
Func<T, U, V>
Operators: CombineLatest
IObservable<V> CombineLatest(this IObservable<T> first,
IObservable<U> second,
Func<T, U, V> selector);
IO<T> first
IO<V> result
IO<U> second
Func<T, U, V>
Operators: SelectMany
IObservable<U> SelectMany(this IObservable<T> source,
Func<T, IObservable<U>> selector);
IO<T> source
IO<U> result
IO<U>
IO<U>
Hot and Cold Observables
o Hot observables are active even without subscribers
o Cold observables are activated upon subscription
Observable Events
Observable.FromEvent wraps event
This pattern avoids Reflection
IObservable<IEvent<MouseEventArgs>> mms =Observable.FromEvent<MouseEventArgs>(myControl, ”MouseMove”);
public static IObservable<IEvent<MouseEventArgs>> GetMouseMove(this Control c){
return Observable.FromEvent<MouseEventHandler,MouseEventArgs>(h => new MouseEventHandler(h),h => c.MouseMove += h,h => c.MouseMove -= h);
}
.NET Asynchronous Programming Model (APM)
o The .NET pattern to invoke methods asynchronously
o Has been there since .NET 1.0
o Components expose BeginX and EndX methodso Delegate.BeginInvoke
o Control.BeginInvoke
o Stream.BeginRead
o Web Service Proxies
o Completion can be notified in three different wayso AsyncCallback delegate
o IAsynchResult.AsyncWaitHandle being signalled
o Polling IAsyncResult.IsCompleted
Observable Async Pattern
Observable.FromAsyncPattern wraps Begin... and End... methods
Stream stream = ...byte[] buffer = new byte[1000];
Func<IObservable<int>> f = Observable.FromAsyncPattern<int>(stream.BeginRead, stream.EndRead);
IObservable<int> result = f(buffer, 0, buffer.Length);
Subjects
o A Subject implements both IObservable<T> and IObserver<T>
o Acts as a channel or pipeline with two ports/endpoints
o Building block for custom observables
o Can implement features like caching, buffering and time shifting
SubjectIObservable<T> IObserver<T>
Subject<int> s = new Subject<int>();s.Subscribe(Console.WriteLine);s.OnNext(42);return s.AsObservable();
Joins
o Lets us model more complex event patterns
o Algebraic syntax for building rules
var bingSearcher = BingAPI.Search(...);var googleSearcher = GoogleAPI.Search(...);var yahooSearcher = YahooAPI.Search(...);
IObservable<SearchComparison> searchComparisons = Observable.Join(bingSearcher.And(googleSearcher).Then(
(b, g) => new SearchComparison(new BingReader(b), new GoogleReader(g)),bingSearcher.And(yahooSearcher).Then(
(b, y) => new SearchComparison(new BingReader(b), new YahooReader(y)),googleSearcher.And(yahooSearcher).Then(
(g, y) => new SearchComparison(new GoogleReader(g), new YahooReader(y))));
Real-World Example
ASP.NET HttpHandler for file downloads
http//company.com/download.ashx?id=123 http//internalserver/getfile.asp?id=123
Rx for JavaScript
o Brings similar capabilities to client script
o Integrates with jQuery events
(Rx.Observable.FromJQueryEvent)
o Also supports Script#
Resources
http://channel9.msdn.com/tags/Rx/
http://blogs.msdn.com/rxteam/
http://blogs.msdn.com/jeffva/
http://codebetter.com/blogs/matthew.podwysocki/
http://rxwiki.wikidot.com
Questions?
Next Seminar
Claims Based Identity med WIF
och
Nyheter i WCF 4.0
Malmö 26/5 8:00
Linköping 27/5 8:00
Stockholm 27/5 17:00