An introduction to the Reactive Extensions (Rx) framework by Microsoft. Rx provides a simpler event model for handling streams of events in asynchronous and event based programs
DSPy a system for AI to Write Prompts and Do Fine Tuning
Introduction to Reactive Extensions
1. 1
Introduction to Reactive Extensions
Peter Goodman
An Introduction to Reactive
Extensions
2. 2
Introduction to Reactive Extensions
What are Reactive Extensions?
3. 3
Introduction to Reactive Extensions
What are Reactive Extensions?
4. 4
Introduction to Reactive Extensions
What are Reactive Extensions?
5. 5
Introduction to Reactive Extensions
What are Reactive Extensions?
6. 6
Introduction to Reactive Extensions
Events in .Net
form1.MouseMove += (sender, args) => {
if (args.Location.X == args.Location.Y)
// I’d like to raise another event
};
form1.MouseMove -= /* what goes here? */
7. 7
Introduction to Reactive Extensions
Collections are Enumerables
interface IEnumerable<out T>
{
IEnumerator<T> GetEnumerator();
}
interface IEnumerator<out T> : IDisposable
{
bool MoveNext();
T Current { get; }
void Reset();
}
8. 8
Introduction to Reactive Extensions
What if events were collections?
Collection
Move Next Move Next Move Next Move Next Move Next Move Next
Event Stream
TIME
OnNext OnNext OnNext OnNext OnNext OnNext
13. 13
Introduction to Reactive Extensions
Generating values and Subscribing
A variant with time notion Hypothetical anonymous
exists (GenerateWithTime) iterator syntax in C#
o = Observable.Generate( e = new IEnumerable<int> {
0, for (int i = 0;
i => i < 10, i < 10;
i => i + 1, i++)
i => i * i yield return i * i;
);
};
Asynchronous Synchronous
o.Subscribe(x => { foreach (var x in e) {
Console.WriteLine(x); Console.WriteLine(x);
}); }
14. 14
Introduction to Reactive Extensions
Subscribing
IObservable<int> o = Observable.Create<int>(observer => {
// Assume we introduce concurrency (see later)…
observer.OnNext(42);
observer.OnCompleted();
});
IDisposable subscription = o.Subscribe(
onNext: x => { Console.WriteLine("Next: " + x); },
onError: ex => { Console.WriteLine("Oops: " + ex); },
onCompleted: () => { Console.WriteLine("Done"); }
);
15. 15
Introduction to Reactive Extensions
DEMO
Generating events and subscribing to them
16. 16
Introduction to Reactive Extensions
Observable Querying
Observables are sources of data
Data is sent to you (push based)
Extra (optional) notion of time.
Hence we can query over them
// Producing an IObservable<Point> using Select
var from in Observable MouseEventArgs
select .Location
// Filtering for the first bisector using Where
var from in
where
select
17. 17
Introduction to Reactive Extensions
DEMO
Querying, Composition and introducing Concurrency
18. 18
Introduction to Reactive Extensions
Introducing Asynchrony
An Asynchronous operation can be thought of as an
Observable that returns a single value and completes.
FromAsync
Takes an APM method pair (BeginExecute, EndExecute) and
creates an Observable
ToAsync
Takes a method and creates an Observable (Like TPL)
19. 19
Introduction to Reactive Extensions
Introducing Concurrency
Many operators in Rx introduce Concurrency
Throttle
Interval
Delay
BufferWithTime
Generally they provide an overload to supply a Scheduler
ImmediateScheduler – Static Immediate
CurrentThreadScheduler – Placed on a queue for the current thread
NewThreadScheduler – Spawn a new Thread
DispatcherScheduler - Silverlight
TaskPoolScheduler - TPL
ThreadPoolScheduler
20. 20
Introduction to Reactive Extensions
Concurrency and Synchronization
•
var Observable.Return Scheduler.ThreadPool
" "
•
.ObserveOnDispatcher()
" "
21. 21
Introduction to Reactive Extensions
DEMO
Synchronization
22. 22
Introduction to Reactive Extensions
Rx for JavaScript (RxJS)
Parity with Rx for .NET
Set of operators
Taming asynchronous JS
JavaScript-specific bindings
jQuery
ExtJS
Dojo
Prototype
YUI3
MooTools
Bing APIs
23. 23
Introduction to Reactive Extensions
DEMO
Rx for JavaScript
24. 24
Introduction to Reactive Extensions
Reactive Extensions
Questions?
Who am I?Rx was developed by the Cloud Programmability Team
- Composing gives us a hint at the Linq style fluent API
Async and event-based programs. Recent initiatives including TPL, async/await etc
You can’t pass an event aroundThe syntax is very unique and requires cleaning up of subscriptionsYou can’t compose events into new events easily.
Lets look at an ordinary collection in .NetNotice in IEnumerable we FETCH an EnumeratorMoveNext pulls the next value from the collection synchronously into Current. It could have just as easily returned the current value from MoveNextReset is an oddity of historyWe are done when there are no more items and MoveNext returns true
Observables turn the whole thing on it’s headNotice in Iobservable we get FED an ObserverOnNext pushed the next value from onto the collection asynchronously. OnError occurs when an exception has happened.OnCompleted happens when there are no more items
Observable.Return(42).Subscribe(Console.WriteLine)Observable.Range(0,20). Subscribe(Console.WriteLine)Observable.Generate( 0,i => i < 20, i => i+1, i => i*i) .Subscribe(Console.WriteLine);Observable.Generate( 0,i => i < 20, i => i+1, i => i*i) .Subscribe(Console.WriteLine);var sub = Observable.Interval(TimeSpan.FromSeconds(1)).Subscribe(Console.WriteLine);var sub = Observable.Interval(TimeSpan.FromSeconds(1)).Take(3).Subscribe(Console.WriteLine);Observable.Interval(TimeSpan.FromSeconds(1)).Take(3).Subscribe(Console.WriteLine, e => { }, () => Console.WriteLine("Complete"));
Observable.Range(0, 20).Where(x => x % 2 ==0).Subscribe(Console.WriteLine)Observable.Range(0, 20).Where(x => x % 2 ==0).Select(x => x*x).Subscribe(Console.WriteLine)Observable.Range(0, 20).Zip(Observable.Interval(TimeSpan.FromSeconds(1)), (x,y) => x).Where(x => x % 2 == 0).Subscribe(Console.WriteLine);
From Blank AutoCompleteShow project structureCreate search based off property changed event handler** How would we do this with Rx?**Create propertyChanges, searchTextChanges and subscribeRun** What about blocking the UI thread?**Add doSearch, select many and subscriptionRun ** What about the exception?**ObserveOnDispatcherRun** What about too many searches?**Throttle** What about adding support for pressing enter?**TextBoxEnterCommand (Merge)** What about the duplicates?**DistinctUntilChanged** What about results coming back out of sequence?** (Temporarily remove throttle to show)TakeUntil