MILAN 20/21.11.2015
Talk title: Reactive Extensions 101
Tamir Dresher – CodeValue - @tamir_dresher
• Software Architect, Consultant and Instructor
• Software Engineering Lecturer @ Ruppin
Academic Center
@tamir_dresher
tamirdr@codevalue.net
http://www.TamirDresher.com.
Your headache relief pill to Asynchronous and
Event based applications
Async
Push
Triggers
Events
Reactive Extensions
Reactive Programming concentrates
on the propagation of changes and
their effects
simply put, how to react to
changes and create dataflows
that depend on them
Reactive Programming
Social
media
IoT
GPS
External Services
Your System
So Many Sources…
Source/
Producer
Target/
Consumer
Producer-Consumer
Source/
Producer
Target/
Consumer
Source/
Producer
Source/
Producer
Target/
Consumer
Target/
Consumer
Producer-Consumer
IEnumerable<Message> LoadMessages(string hashtag)
{
var statuses = facebook.Search(hashtag);
var tweets = twitter.Search(hashtag);
var updates = linkedin.Search(hashtag);
return statuses.Concat(tweets).Concat(updates);
}
Twitter App
Linkedin
Facebook
Pull Model
???? LoadMessages(string hashtag)
{
facebook.Search(hashtag);
twitter.Search(hashtag);
linkedin.Search(hashtag);
}
DoSomething( )msg
Push Model
observable observer
Subscribe(observer)
subscription
OnNext(X1)
OnNext(Xn)
⁞
⁞
IDisposable
Observables and Observers
OnCompleted()
OnError(Exception)

observable observer
⁞
Observables and Observers
namespace 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();
}
}
Interfaces
MILAN 20/21.11.2015
Creating Observables
IObservable<Message> ObserveMessages(string hashtag)
{
}
return Observable.Create( async (o) =>
{
});
var messages = await GetMessagesAsync(hashtag);
foreach(var m in messages)
{
o.OnNext(m);
}
o.OnCompleted();
Pull To Push
IObservable<Message> ObserveMessages(string hashtag)
{
}
return Observable.Defer( async () =>
{
});
var messages = await GetMessagesAsync(hashtag);
return message.ToObservable();
Built-in Converters
Observable.Merge(
facebook.ObserveMessages(hashtag),
twitter.ObserveMessages(hashtag),
linkedin.ObserveMessages(hashtag)
);
Built-in Operators
Observable.Range(1, 10)
.Subscribe(x => Console.WriteLine(x));
Observable.Interval(TimeSpan.FromSeconds(1))
.Subscribe(x => Console.WriteLine(x));
Observable.FromEventPattern(SearchBox, "TextChanged")⁞
⁞
1 sec 1 sec
Observables Factories
⁞
MILAN 20/21.11.2015
Observable Queries (Rx Operators)
Filtering Projection Partitioning Joins Grouping Set
Element Generation Quantifiers Aggregation Error HandlingTime and
Concurrency
Where
OfType
Select
SelectMany
Materialize
Skip
Take
TakeUntil
CombineLatest
Concat
join
GroupBy
GroupByUntil
Buffer
Distinct
DistinctUntilChanged
Timeout
TimeInterval
ElementAt
First
Single
Range
Repeat
Defer
All
Any
Contains
Sum
Average
Scan
Catch
OnErrorResumeNext
Using
Operator2 Creates an IObservable<T3>
IObservable parameters
Operator
1
Subscribe( )
observer
observable
… Operator
N
Operator1
Creates an IObservable<T2>
IObservable<T>
Original source
observer
Subscribe
Composability
g(x)
f(x)
Observable Query Pipeline
Reactive Search
1. At least 3 characters
2. Don’t overflow server (0.5 sec delay)
3. Don’t send the same string again
4. Discard results if another search was
requested
Reactive Search - Rules
Var textChanged =
Observable.FromEventPattern(txt, “TextChanged”)
.Select(_=>txt.Text);
textChanged
.Where(text=>text.Length>3)
.Throttle(TimeSpan.FromSeconds(0.5))
.DistinctUntilChanged()
.SelectMany(text => SearchAsync(text))
.Switch()
.Subscribe(/*handle the results*/);
var $input = $('#input'),
$results = $('#results');
Rx.Observable.fromEvent($input, 'keyup')
.map(e => e.target.value)
.filter(text => text.length > 3)
.throttle(500 /* ms */)
.distinctUntilChanged()
.flatMapLatest(searchWikipedia)
.subscribe(data => {
var res = data[1];
$results.empty();
$.each(res, (_, value) => $('<li>' + value + '</li>').appendTo($results));
}, error => {
/* handle any errors */
$results.empty();
$('<li>Error: ' + error + '</li>').appendTo($results);
});
MILAN 20/21.11.2015
Abstracting Time and Concurrency
Thread Pool
Task Scheduler
other
Schedulers
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);
}
//
// Runs a timer on the default scheduler
//
IObservable TimeSpan
//
// Every operator that introduces concurrency
// has an overload with an IScheduler
//
IObservable T TimeSpan
IScheduler scheduler
Parameterizing Concurrency
textChanged
.Throttle(TimeSpan.FromSeconds(0.5),
DefaultScheduler.Instance)
.DistinctUntilChanged()
.SelectMany(text => SearchAsync(text))
.Switch()
.Subscribe(/*handle the results*/);
//
// runs the observer callbacks on the specified
// scheduler.
//
IObservable T T IScheduler
//
// runs the observer subscription and unsubsciption on
// the specified scheduler.
//
IObservable T T IScheduler
Changing Execution Context
textChanged
.Throttle(TimeSpan.FromSeconds(0.5))
.DistinctUntilChanged()
.SelectMany(text => SearchAsync(text))
.Switch()
.ObserveOn(DispatcherScheduler.Current)
.Subscribe(/*handle the results*/);
Changing Execution Context
textChanged
.Throttle(TimeSpan.FromSeconds(0.5))
.DistinctUntilChanged()
.SelectMany(text => SearchAsync(text))
.Switch()
.ObserveOnDispatcher()
.Subscribe(/*handle the results*/);
Changing Execution Context
http://blogs.msdn.com/b/rxteam/archive/2012/06/14/testing-rx-queries-using-virtual-time-scheduling.aspx
Virtualizing Time
Your headache relief pill to Asynchronous and
Event based applications
Async
Push
Triggers
Events
Reactive Extensions
Thank You
www.manning.com/dresher www.reactivex.io github.com/Reactive-Extensions
Discount code:
ctwcodemot
MILAN 20/21.11.2015 - Tamir Dresher – Rx 101
Leave your feedback on Joind.in!
https://m.joind.in/event/codemotion-milan-2015
Presenter contact details
t: @tamir_dresher
e: tamirdr@codevalue.net
b: TamirDresher.com
w: www.codevalue.net

Rx 101 Codemotion Milan 2015 - Tamir Dresher

Editor's Notes

  • #3 Proud creators of OZCode
  • #4 MultiThreading or IO Concurrency and Parallel Deadlocks and race conditions Event handles – spread code fragments Memory Leaks – neglected event handlers