Upload
tamir-dresher
View
1.423
Download
10
Embed Size (px)
DESCRIPTION
Presentations from the june meeting of IDNDUG http://ariely.info/Communities/IDNDUG/IDNDUG19thJune2013/tabid/171 The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators. Using Rx, developers represent asynchronous data streams with Observables, query asynchronous data streams using LINQ operators, andparameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, Rx = Observables + LINQ + Schedulers
Citation preview
Tamir DresherSenior Software ArchitectJune 19, 2013
Slides: Bart De Smet
Reactive Extensions (RX)
About Me
• Software architect, consultant and instructor• Technology addict• 10 years of experience• .NET and Native Windows Programming• http://www.TamirDresher.com.
Socialmedia
Stock tickers
RSS feeds
GPS
Server managementUI e
vents
Applications And Data
Reactive Extensions Architecture
Concurrency
IScheduler TimeThreads Cloud Dispatchers
Event Streams
IObservable<T>
IObserver<T>ISubject<T>
LINQ to Events
from quote in stockwhere quote.Symbol == “MSFT”select quote.ValueProjectionFi
lterin
gAggregating
Gro
upin
g Joins
WindowingSharing
SamplingThrottling Timeout
Merging
Recovery
The building blocks
• Observables– Producers (.NET events, WinRT Events, Sensors, APM method etc.)
• Observers– Consumers
Observable
Subscribe
Observer
Essential Interfacesnamespace System{
public interface IObservable<out T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<in T>{
void OnNext(T value); void OnError(Exception error);
void OnCompleted;)(} }
Notification Grammar
OnNext(42)
source1
OnNext(43) OnCompleted
OnNext(“Hello”)
source2
OnError(error)
OnNext* (OnError | OnCompleted)?
Limitations of .NET Events
exchange.StockTick += (sender, args) =>{ if (args.Quote.Symbol == “MSFT”) { // Imperative code }};
exchange.StockTick -= /* what goes here? */;
Can’t pass around Hidden data source
Hard resource maintenance
Lack of composition
Observable Sequences to the Rescue
IObservable<Quote> stockQuotes = …;
var msft = stockQuotes
.Where(quote => quote.Symbol == “MSFT”);
var subscription = msft.Subscribe(quote => /* … */);
subscription.Dispose();
Easy resource maintenance
Can define query operators
ReactDictionary web
service
Asynchronous request
ReactionReactiveReactor
IObservable<string>
IObservable<DictionaryWord[]>Data binding
on UI thread
“React”
Dictionary Suggest
Demo
Converting Events and Asynchronous Methods
// Convert the TextChanged event to IObservable<string>var input = (from evt in Observable.FromEventPattern(txt, “TextChanged”) select ((TextBox)evt.Sender).Text) .Throttle(TimeSpan.FromSeconds(0.5)) .DistinctUntilChanged();
// Convert asynchronous proxy methods to Func<string, IObservable<string[]>>var lookup = Observable.FromAsyncPattern<string, string[]>(svc.BeginLookup, svc.EndLookup);
// Compose both sources using a queryvar res = from term in input from words in lookup(term).TakeUntil(input) select words;
No longer needed in Rx v2.0 for .NET 4.5, using Task<T>
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
from tick in ticks
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
27.01 27.96 31.21 30.73
MSFT
21.75 22.54 20.98
INTC
from tick in ticks
group tick by tick.Symbol into company
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
MSFT
INTC
from tick in ticks
group tick by tick.Symbol into companyfrom openClose in company.Buffer(2, 1)
[27.01, 27.96] [27.96, 31.21] [31.21, 30.73]
[21.75, 22.54] [22.54, 20.98]
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
MSFT
INTC
from tick in ticksgroup tick by tick.Symbol into companyfrom openClose in company.Buffer(2, 1)
let diff = (openClose[1] – openClose[0]) / openClose[0]
0.034 0.104 -0.015
0.036 -0.069
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
MSFT
INTC
from tick in ticksgroup tick by tick.Symbol into companyfrom openClose in company.Buffer(2, 1)let diff = (openClose[1] – openClose[0]) / openClose[0]
where diff > 0.1
0.034 0.104 -0.015
0.036 -0.069
Stock Trade AnalysisMSFT27.01
ticks
INTC21.75
MSFT27.96
MSFT31.21
INTC22.54
INTC20.98
MSFT30.73
from tick in ticksgroup tick by tick.Symbol into companyfrom openClose in company.Buffer(2, 1)let diff = (openClose[1] – openClose[0]) / openClose[0]where diff > 0.1
select new { Company = company.Key, Increase = diff }
res
Company = MSFTIncrease = 0.104
Reactive Extensions Architecture
Event Streams
IObservable<T>
IObserver<T>ISubject<T>
LINQ to Events
from quote in stockwhere quote.Symbol == “MSFT”select quote.ValueProjectionFi
lterin
g
AggregatingG
roup
ing
Joins
Windowing
Sharing
Sampling
Throttling Timeout
Merging
Recovery
The Role of SchedulersParameterize Concurrency
//// Runs a timer on the default scheduler//IObservable<long> Timer(TimeSpan dueTime);
//// Every operator that introduces concurrency// has an overload with an IScheduler//IObservable<long> Timer(TimeSpan dueTime, IScheduler scheduler);
The Role of SchedulersSynchronization
var xs = Observable.Return(42, Scheduler.ThreadPool);xs.Subscribe(x => lbl.Text = "Answer = " + x);
xs.ObserveOn(new ControlScheduler(frm)) .Subscribe(x => lbl.Text = "Answer = " + x);xs.ObserveOn( frm ) .Subscribe(x => lbl.Text = "Answer = " + x);
The IScheduler Interface
public interface IScheduler{ DateTimeOffset Now { get; }
IDisposable Schedule<TState>( TState state, Func<IScheduler, TState, IDisposable> action);
IDisposable Schedule<TState>( TimeSpan dueTime, TState state, Func<IScheduler, TState, IDisposable> action);
IDisposable Schedule<TState>( DateTimeOffset dueTime, TState state, Func<IScheduler, TState, IDisposable> action);}
Operational Layering of Rx
public static IObservable<T> Return<T>(T value, IScheduler scheduler){ return Observable.Create<T>(observer => { // Serialize state to scheduler; return ability to cancel return scheduler.Schedule(new { value, observer }, (_, x) => { x.observer.OnNext(x.value); x.observer.OnCompleted(); return Disposable.Empty; // No recursive work }); });}
Virtualizing Time for Testing
var scheduler = new TestScheduler();
var input = scheduler.CreateHotObservable( OnNext(300, “Bart De Smet”), OnNext(400, “Erik Meijer”), OnCompleted<string>(500));
var results = scheduler.Start(() => from name in input select name.Length);
results.Messages.AssertEqual( OnNext(300, 12), OnNext(400, 11), OnCompleted<int>(500));
The Asynchronous Programming Landscape
Synchronous Asynchronous
Sing
le v
alue
(1)
Mul
tiple
val
ues
(*)
Func<T> Task<T>
IEnumerable<T> IObservable<T>
var y = f(x);var z = g(y);
var y = await fAsync(x);var z = await gAsync(y);
var res = from p in products where p.Name == “Rx” select p.Price;
foreach (var x in res) …
var res = from s in stocks where s.Symbol == “MSFT” select q.Quote
res.Subscribe(x => …
Summary
• Tame your event streams using Rx and LINQ!
• Download Rx today!– Through http://www.microsoft.com/download (search for Rx SDK)– Using NuGet @ www.nuget.org (search for Rx-Main)
• Watch videos at http://channel9.msdn.com/tags/Rx
Related Content/* Only get the value from each key up */var keyups = Rx.Observable.fromEvent(input, 'keyup') .select(function (e) { return e.target.value; }) .where(function (text) { return text.length > 2; });
/* Now throttle/debounce the input for 500ms */var throttled = keyups .throttle(500 /* ms */);
/* Now get only distinct values, so we eliminate the arrows */var distinct = keyups .distinctUntilChanged();
void PrintPrimes(int n) { std::cout<<"Rx: first "<<n<<" primes squared"<<endl; auto values = rxcpp::Range(2); rxcpp::from(values) .where(IsPrime) .select([](int x) { return std::make_pair(x, x*x); }) .take(n) .for_each(rxcpp::MakeTupleDispatch(
[](int p, int s) { cout<<p<<" =square=> "<<s<<endl; }));
}
RX++RxJS
28
ReactiveUIpublic class NewUserViewModel : ReactiveObject{
// This is ReactiveUI's version of implementing INotifyPropertyChangedstring _Password,_PasswordConfirmation;public string Password {
get { return _Password; }set { this.RaiseAndSetIfChanged(x => x.Password, value); }
}public string PasswordConfirmation {
get { return _PasswordConfirmation; }set { this.RaiseAndSetIfChanged(x => x.PasswordConfirmation, value); }
}ICommand OkCommand { get; protected set; }public NewUserViewModel(){
var canHitOk = this.WhenAny(x => x.Password, x => x.PasswordConfirmation,(pass, confirm) => (pass.Value == confirm.Value && pass.Value.Length > 3));OkCommand = new ReactiveCommand(canHitOk);
}
Resources
• Channel 9– Curing Your Event Processing Blues with Reactive Extensions (Rx) -
Bart De Smet http://msdn.microsoft.com/en-us/library/windowsazure/jj860549.aspx
• IntroToRx.com– IntroToRx.com is the online resource for getting started with
the Reactive Extensions to .Net.• www.reactiveui.com
https://github.com/reactiveui/ReactiveUI.Samples
Presenter contact detailsc: +972-52-4772946e: [email protected]: TamirDresher.comw: www.codevalue.net