Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Reactive ExtensionsWorkshop<br />Ryan Riley & Wes Dyer<br />
Logistics<br />30 minute sections<br />10 minutes presentation<br />10 minutes coding<br />10 minutes discussion<br />New ...
Where can I get them?<br />Install with NuGet<br />Download at MSDN Data Developer Center<br />
Outline<br />Introduction to Rx<br />A Unified Programming Model<br />The Power of Rx<br />RxJS<br />Schedulers<br />Event...
introduction to rx<br />like events but much better<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Reactive Programming<br />In computing, reactive programming is a programming paradigm oriented around data flows and the ...
Why should I care?<br />GPS<br />RSS      feeds<br />Stock tickers<br />Social<br />media<br />UI events<br />Server manag...
Reactive Programming using Events<br />Declare<br />eventAction<int> E;<br />Publish<br />E(42);<br />Subscribe<br />	E +=...
Reactive Programming using Rx<br />Declare<br />ISubject<int> S = newSubject<int>();<br />Publish<br />S.OnNext(42);<br />...
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
classProgram {<br />ISubject<int> S = newSubject<int>();<br />static void Main() {<br />var p = newProgram();<br />p.S.Sub...
Separate Publish from Subscribe <br />Both<br />Publish<br />Subscribe<br />
First-Class “Events”<br />An object is first-class when it:<br />can be stored in variables and data structures<br />can b...
First-Class “Events”<br />// stored<br />IObservable<string> textChanged = …;<br />// passed<br />voidProcessRequests(IObs...
Punctuation<br />classIObserver<in T><br />{<br />voidOnNext(T value);<br />voidOnError(Exception error);<br />voidOnCompl...
Contract<br />Grammar: OnNext* [OnCompleted | OnError]<br />Serialized execution of observer’s methods<br />0<br />1<br />...
Challenge: Simple Transformation<br />Implement Events.LengthChanged<br />ImplementObservables.LengthChanged<br />Output s...
Answer<br />Events<br />Observables<br />
Bridging from the Existing World<br />query asynchronous data streams<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Empty<br />// complete immediately<br />Observable.Empty<int>();<br />
Return<br />// return 1 value<br />Observable.Return(1);<br />1<br />
Throw<br />// throw an exception<br />Observable.Throw(newException());<br />
Never<br />// never complete<br />Observable.Never<int>();<br />
Range<br />// return three values starting with 0<br />Observable.Range(0, 3);<br />1<br />2<br />0<br />
ToEnumerable / ToObservable<br />// enumerable to observable<br />Enumerable.Range(0, 3).ToObservable();<br />// observabl...
Generate<br />// observable for loop<br />Observable.Generate(<br />    0,<br />   i => i < 3,<br />    i => i + 1,<br /> ...
Create<br />// anything you please<br />Observable.Create<int>(observer =><br />{<br />IDisposableb = newBooleanDisposable...
classProgram {<br />  static void Main() {<br />    Labellbl = newLabel();<br />Formfrm = newForm {<br />     Controls = {...
classProgram {<br />  static void Main() {<br />    Labellbl = newLabel();<br />Formfrm = newForm {<br />     Controls = {...
Challenge<br />Complete DictionarySuggest<br /><ul><li>Create an Observable from the TextChangedevent
Create an Observable from an asynchronous web request
Combine these two observables to react to text input changes to return web service results</li></li></ul><li>Answer<br />
The Power of Rx<br />taking control<br />
Monitoring<br />// anything you please<br />var input = Observable<br />    .FromEventPattern(txt, "TextChanged")<br />   ...
Too Many Events<br />
Duplication<br />
Race Condition<br />
Challenge<br />Find and apply the operators to fix these issues in DictionarySuggest<br />
Answer<br />
JavaScript<br />
Challenge<br />Port DictionarySuggest to RxJS<br />
Answer<br />
Schedulers<br />parameterizing concurrency<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Parameterizing Concurrency<br />Observable.Timer(TimeSpan.FromSeconds(5))<br />Which timer?<br />System.Threading.Timer?<b...
Scheduler Abstraction<br />execution context<br />clock<br />execution policy<br />
Scheduler Interface<br />interfaceIScheduler<br />{<br />DateTimeOffset Now { get; }<br />IDisposable Schedule(Action work...
Operational Layering<br />Operators<br />varxs = Observable.Range(1, 10, <br />Scheduler.ThreadPool);<br />var q = from x ...
Operational Layering<br />Operators<br />Observables<br />varxs = newRangeObservable<int>(1, 10, <br />Scheduler.ThreadPoo...
Operational Layering<br />Operators<br />Observables<br />var n = 0;<br />Scheduler.ThreadPool.Schedule(self => {<br />if ...
Operational Layering<br />Operators<br />Observables<br />var n = 0;<br />Action<object> work = null;<br />work = _ =><br ...
One Interface to Rule Them All<br />
The Problem of Time<br />Operations can take a long time<br />Observable.Timer(TimeSpan.FromYears(1000))<br />
Some operators have time-based semantics<br />Observable.Timer(TimeSpan.FromSeconds(1))<br /> .Buffer(TimeSpan.FromSeconds...
When testing reactive programs, time is the problem.<br />…virtual time is the solution.<br />The Problem of Time<br />
Schedulers Revisited<br />
TestScheduler scheduler = newTestScheduler();<br />IObservable<string> input = scheduler.CreateObservable(<br />OnNext(300...
Implement MainForm.GetQuotes<br />ImplementMainForm.GetQuery<br />Challenge: Historical Data<br />
Answer<br />
event processing<br />the power of LINQ<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Given: Stream of stock ticks<br />Find: 10% daily price increase<br />Event Processing<br />
Windowing<br />MSFT<br />30.73<br />MSFT<br />27.01<br />MSFT<br />27.96<br />INTC<br />21.75<br />MSFT<br />31.21<br />IN...
Aggregation<br />MSFT<br />INTC<br />30.73<br />27.01<br />27.96<br />31.21<br />21.75<br />22.54<br />20.98<br />Aggregat...
Filtering<br />MSFT<br />INTC<br />31.21<br />30.73<br />27.01<br />27.96<br />27.96<br />31.21<br />21.75<br />22.54<br /...
Reduce<br />MSFT<br />INTC<br />27.96<br />31.21<br />Reduce to a single stream: Merge()<br />
Done!<br />27.96<br />31.21<br />
from tick instockTicks<br />group tick bytick.SymbolintosymbolStream<br />from window insymbolStream.Buffer(2, 1)<br />let...
Change MainForm.Query to compute the Average High and Average Low over the past 5 trading days as well as the current Clos...
Answer<br />
Reactive coincidence<br />streaming windows<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Event Duration<br />0<br />2<br />1<br />vs<br />0<br />2<br />1<br />
An Example<br />left <br />left<br />right<br />
Representing Duration<br />begin<br />begin<br />end<br />end<br />Window<br />
Store<br />
Reactive Coincidence<br />Which people are at the store while it is opened?<br />5/5<br />5/6<br />curley<br />moe<br />la...
Reactive Coincidence<br />Which people are at the store while it is opened?<br />5/5<br />5/6<br />moe<br />larry<br />cur...
LINQ Join<br />from opening instoreOpenings<br />join person inpersonArrives<br />onopening.Closeequalsperson.Leavesinto g...
Change query in MainForm.MainForm to compute a stream of deltas when the mouse is down<br />Challenge: Drag and Drop<br />
Answer<br />
Programming the cloud<br />a glimpse into the future<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Distributed Queries<br />Cloud<br />results<br />query<br />
Observable.Timer(<br />TimeSpan.FromSeconds(1),<br />Scheduler.Azure)<br /> .ObserveLocally()<br /> .Subscribe(Console.Wri...
Pass-by-Value<br />	[Serializable] classMyType { … }<br />Pass-by-Reference<br />classMyType : MarshalByRefObject{ … }<br ...
var x = 42;<br />scheduler.Schedule(() =><br />Console.WriteLine(x));<br />classClosure {<br />public intx;<br />public vo...
interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state, Action<T> work);<br /> …<br />}<br />Scheduler Interfa...
var x = 42;<br />scheduler.Schedule(<br /> x,<br /> state =><br />Console.WriteLine(state));<br />static void M(int state)...
scheduler.Schedule(42, x =><br />scheduler.Schedule(x + 1, y =><br />Console.WriteLine(y)));<br />Nested Scheduling<br />
Distributed Scheduling<br />cloud<br />Scheduler<br />
interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state,<br />   Action<IScheduler, T> work);<br /> …<br />}<br...
scheduler.Schedule(42, (s, x) =><br />s.Schedule(x + 1, y =><br />Console.WriteLine(y)));<br />Nested Scheduling<br />
Fan-out Scheduling<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Schedule...
var d = scheduler.Schedule(42, (s, x) => {<br />var d1 = s.Schedule(x + 1, Console.WriteLine);<br />var d2 = s.Schedule(x ...
interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state,<br />Func<IScheduler, T, IDisposable> work);<br /> …<b...
var d = scheduler.Schedule(42, (s, x) => {<br />var d1 = s.Schedule(x + 1, Console.WriteLine);<br />vard2 = s.Schedule(x +...
scheduler.Schedule(42, (state, self) =><br /> {<br />Console.WriteLine(state);<br />   self(state + 1);  });<br />Easy Rec...
Change Program.Main to use the AppDomainScheduler<br />ReimplementGenerateObservable.Subscribe<br />Challenge: AppDomains<...
Answer<br />
Continuations Everywhere<br />continuation-passing style used elsewhere<br />
Ruby<br />1..10.each do |x|    puts x * xend<br />
AJAX<br />$.ajax({<br />	url: 'http://en.wikipedia.org/w/api.php',<br />dataType: 'jsonp',<br />data: {<br />		action: 'op...
node.js<br />var net = require('net');<br />var server = net.createServer(function (socket) {<br />socket.write("Echo serv...
Challenge<br />Using Rx, build a TCP server that works in a similar manner to node.js.<br />
The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to...
Nächste SlideShare
Wird geladen in …5
×

Rx workshop

3.644 Aufrufe

Veröffentlicht am

Workshop slides from the Alt.Net Seattle 2011 workshop. Presented by Wes Dyer and Ryan Riley. Get the slides and the workshop code at http://rxworkshop.codeplex.com/

Veröffentlicht in: Technologie, Sport
  • microsoft rx presentation
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Rx workshop

  1. 1. Reactive ExtensionsWorkshop<br />Ryan Riley & Wes Dyer<br />
  2. 2. Logistics<br />30 minute sections<br />10 minutes presentation<br />10 minutes coding<br />10 minutes discussion<br />New partner every section<br />Prizes for best code during each section<br />
  3. 3. Where can I get them?<br />Install with NuGet<br />Download at MSDN Data Developer Center<br />
  4. 4. Outline<br />Introduction to Rx<br />A Unified Programming Model<br />The Power of Rx<br />RxJS<br />Schedulers<br />Event Processing<br />Reactive Coincidence<br />Continuations Everywhere<br />Programming the Cloud<br />
  5. 5. introduction to rx<br />like events but much better<br />
  6. 6. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  7. 7. Reactive Programming<br />In computing, reactive programming is a programming paradigm oriented around data flows and the propagation of change.<br />http://en.wikipedia.org/wiki/Reactive_programming<br />
  8. 8. Why should I care?<br />GPS<br />RSS feeds<br />Stock tickers<br />Social<br />media<br />UI events<br />Server management<br />
  9. 9. Reactive Programming using Events<br />Declare<br />eventAction<int> E;<br />Publish<br />E(42);<br />Subscribe<br /> E += x => Console.WriteLine(x);<br />
  10. 10. Reactive Programming using Rx<br />Declare<br />ISubject<int> S = newSubject<int>();<br />Publish<br />S.OnNext(42);<br />Subscribe<br />S.Subscribe(x => Console.WriteLine(x));<br />
  11. 11. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  12. 12. classProgram {<br />ISubject<int> S = newSubject<int>();<br />static void Main() {<br />var p = newProgram();<br />p.S.Subscribe(x => Console.WriteLine(x));<br />p.S.OnNext(1);<br />p.S.OnNext(2);<br />p.S.OnNext(3);<br /> }<br />}<br />classProgram {<br />eventAction<int> E;<br />static void Main() {<br />var p = newProgram();<br />p.E += x => Console.WriteLine(x);<br />p.E(1);<br />p.E(2);<br />p.E(3);<br /> }<br />}<br />A Little Example<br />
  13. 13. Separate Publish from Subscribe <br />Both<br />Publish<br />Subscribe<br />
  14. 14. First-Class “Events”<br />An object is first-class when it:<br />can be stored in variables and data structures<br />can be passed as a parameter to a subroutine<br />can be returned as the result of a subroutine<br />can be constructed at runtime<br />has intrinsic identity (independent of any given name)<br />http://en.wikipedia.org/wiki/First-class_object<br />
  15. 15. First-Class “Events”<br />// stored<br />IObservable<string> textChanged = …;<br />// passed<br />voidProcessRequests(IObservable<string> input) {…}<br />// returned<br />IObservable<int> QueryServer() {…}<br />
  16. 16. Punctuation<br />classIObserver<in T><br />{<br />voidOnNext(T value);<br />voidOnError(Exception error);<br />voidOnCompleted();}<br />
  17. 17. Contract<br />Grammar: OnNext* [OnCompleted | OnError]<br />Serialized execution of observer’s methods<br />0<br />1<br />2<br />0<br />1<br />1<br />2<br />0<br />0<br />1<br />2<br />
  18. 18. Challenge: Simple Transformation<br />Implement Events.LengthChanged<br />ImplementObservables.LengthChanged<br />Output should be:<br />
  19. 19. Answer<br />Events<br />Observables<br />
  20. 20. Bridging from the Existing World<br />query asynchronous data streams<br />
  21. 21. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  22. 22. Empty<br />// complete immediately<br />Observable.Empty<int>();<br />
  23. 23. Return<br />// return 1 value<br />Observable.Return(1);<br />1<br />
  24. 24. Throw<br />// throw an exception<br />Observable.Throw(newException());<br />
  25. 25. Never<br />// never complete<br />Observable.Never<int>();<br />
  26. 26. Range<br />// return three values starting with 0<br />Observable.Range(0, 3);<br />1<br />2<br />0<br />
  27. 27. ToEnumerable / ToObservable<br />// enumerable to observable<br />Enumerable.Range(0, 3).ToObservable();<br />// observable to enumerable<br />Observable.Range(0, 3).ToEnumerable();<br />1<br />2<br />0<br />
  28. 28. Generate<br />// observable for loop<br />Observable.Generate(<br /> 0,<br /> i => i < 3,<br /> i => i + 1,<br /> i => i * i<br />);<br />1<br />4<br />0<br />
  29. 29. Create<br />// anything you please<br />Observable.Create<int>(observer =><br />{<br />IDisposableb = newBooleanDisposable();<br /> newThread(() =><br /> {<br />for (inti = 0; i < 3&& !b.IsDisposed; ++i)<br />observer.OnNext(i);<br />observer.OnCompleted();<br /> return () => {};<br /> }).Start();<br /> returnb;<br />});<br />1<br />4<br />0<br />
  30. 30. classProgram {<br /> static void Main() {<br /> Labellbl = newLabel();<br />Formfrm = newForm {<br /> Controls = { lbl}<br /> };<br />frm.MouseMove+= (s, args) => {};<br /> }<br />}<br />classProgram {<br /> static void Main() {<br />Labellbl = newLabel();<br />Formfrm = newForm {<br /> Controls = { lbl }<br />};<br />varmouseMoves= Observable<br />.FromEventPattern<MouseEventHandler,<br />MouseEventArgs>(<br /> x => frm.MouseMove += x,<br /> x => frm.MouseMove -= x);<br />mouseMoves.Subscribe(evt => {});<br /> }<br />}<br />Using Events<br />
  31. 31. classProgram {<br /> static void Main() {<br /> Labellbl = newLabel();<br />Formfrm = newForm {<br /> Controls = { lbl}<br /> };<br />frm.MouseMove+= (sender, args) =><br /> {<br /> if(args.Location.X==<br />args.Location.Y)<br /> {<br />lbl.Text =<br />args.Location.ToString();<br /> }<br /> };<br />Application.Run(frm);<br /> }<br />}<br />classProgram {<br /> static void Main() {<br />Labellbl = newLabel();<br />Formfrm = newForm {<br /> Controls = { lbl }<br />};<br />varmouseUps = …;<br />varmouseMoves= …;<br />varspecificMoves =<br /> fromup inmouseUps<br /> frommove inmouseMoves<br /> letlocation = move.EventArgs.Location<br /> wherelocation.X == location.Y<br /> selectnew { location.X, location.Y };<br /> using(specificMoves<br /> .Subscribe(evt => lbl.Text= evt.ToString()))<br /> {<br />Application.Run(frm);<br /> }<br /> }<br />}<br />LINQ to Events<br />
  32. 32. Challenge<br />Complete DictionarySuggest<br /><ul><li>Create an Observable from the TextChangedevent
  33. 33. Create an Observable from an asynchronous web request
  34. 34. Combine these two observables to react to text input changes to return web service results</li></li></ul><li>Answer<br />
  35. 35. The Power of Rx<br />taking control<br />
  36. 36. Monitoring<br />// anything you please<br />var input = Observable<br /> .FromEventPattern(txt, "TextChanged")<br /> .Select(evt => ((TextBox)evt.Sender).Text)<br /> .Timestamp()<br /> .Do((Timestamped<string> evt) => Console.WriteLine(evt))<br /> .Select(evt => evt.Value)<br /> .Where(evt => evt.Length > 4)<br /> .Do(evt => Console.WriteLine(evt));<br />
  37. 37. Too Many Events<br />
  38. 38. Duplication<br />
  39. 39. Race Condition<br />
  40. 40. Challenge<br />Find and apply the operators to fix these issues in DictionarySuggest<br />
  41. 41. Answer<br />
  42. 42. JavaScript<br />
  43. 43. Challenge<br />Port DictionarySuggest to RxJS<br />
  44. 44. Answer<br />
  45. 45. Schedulers<br />parameterizing concurrency<br />
  46. 46. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  47. 47. Parameterizing Concurrency<br />Observable.Timer(TimeSpan.FromSeconds(5))<br />Which timer?<br />System.Threading.Timer?<br />System.Timers.Timer?<br />System.Windows.Forms.Timer?<br />System.Windows.Threading.Timer?<br />Sleep on the current thread?<br />… ?<br />
  48. 48. Scheduler Abstraction<br />execution context<br />clock<br />execution policy<br />
  49. 49. Scheduler Interface<br />interfaceIScheduler<br />{<br />DateTimeOffset Now { get; }<br />IDisposable Schedule(Action work);<br />IDisposable Schedule(TimeSpandueTime, Action work);IDisposable Schedule(DateTimeOffsetdueTime, Action work);}<br />
  50. 50. Operational Layering<br />Operators<br />varxs = Observable.Range(1, 10, <br />Scheduler.ThreadPool);<br />var q = from x inxs<br />where x % 2 == 0<br />select -x;<br />q.Subscribe(Console.WriteLine);<br />
  51. 51. Operational Layering<br />Operators<br />Observables<br />varxs = newRangeObservable<int>(1, 10, <br />Scheduler.ThreadPool);<br />var q = newSelectObservable<int>(<br />newWhereObservable<int>(<br />xs,<br /> x => x % 2 == 0),<br /> x => -x);<br />q.Subscribe(<br /> newLambdaObserver<int>(Console.WriteLine));<br />
  52. 52. Operational Layering<br />Operators<br />Observables<br />var n = 0;<br />Scheduler.ThreadPool.Schedule(self => {<br />if (n < 10) {<br /> if ((n + 1) % 2 == 0)<br />Console.WriteLine(-(n + 1));<br /> n++;<br /> self();<br /> }<br />});<br />Schedulers<br />
  53. 53. Operational Layering<br />Operators<br />Observables<br />var n = 0;<br />Action<object> work = null;<br />work = _ =><br />{<br />if (n < 10) {<br /> if ((n + 1) % 2 == 0)<br />Console.WriteLine(-(n + 1));<br /> n++;<br />ThreadPool.QueueUserWorkItem(null, work);<br /> }};<br />ThreadPool.QueueUserWorkItem(null, work);<br />Schedulers<br />Native Concurrency<br />
  54. 54. One Interface to Rule Them All<br />
  55. 55. The Problem of Time<br />Operations can take a long time<br />Observable.Timer(TimeSpan.FromYears(1000))<br />
  56. 56. Some operators have time-based semantics<br />Observable.Timer(TimeSpan.FromSeconds(1))<br /> .Buffer(TimeSpan.FromSeconds(1))<br />The Problem of Time<br />6<br />0<br />4<br />5<br />1<br />2<br />3<br />0<br />1<br />4<br />2<br />3<br />5<br />6<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />1s<br />
  57. 57. When testing reactive programs, time is the problem.<br />…virtual time is the solution.<br />The Problem of Time<br />
  58. 58. Schedulers Revisited<br />
  59. 59. TestScheduler scheduler = newTestScheduler();<br />IObservable<string> input = scheduler.CreateObservable(<br />OnNext(300, “wes”),<br />OnNext(400, “ryan”),<br />OnCompleted(500));<br />var results = scheduler.Run(() =><br />input.Select(x => x.Length));<br />results.AssertEqual(<br />OnNext(300, 3),<br />OnNext(400, 4),<br />OnCompleted(500));<br />Unit Testing with Schedulers<br />
  60. 60. Implement MainForm.GetQuotes<br />ImplementMainForm.GetQuery<br />Challenge: Historical Data<br />
  61. 61. Answer<br />
  62. 62. event processing<br />the power of LINQ<br />
  63. 63. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  64. 64. Given: Stream of stock ticks<br />Find: 10% daily price increase<br />Event Processing<br />
  65. 65. Windowing<br />MSFT<br />30.73<br />MSFT<br />27.01<br />MSFT<br />27.96<br />INTC<br />21.75<br />MSFT<br />31.21<br />INTC<br />22.54<br />INTC<br />20.98<br />Group by symbol: GroupBy(t => t.Symbol)<br />
  66. 66. Aggregation<br />MSFT<br />INTC<br />30.73<br />27.01<br />27.96<br />31.21<br />21.75<br />22.54<br />20.98<br />Aggregate each day with previous day: Buffer(2, 1)<br />
  67. 67. Filtering<br />MSFT<br />INTC<br />31.21<br />30.73<br />27.01<br />27.96<br />27.96<br />31.21<br />21.75<br />22.54<br />22.54<br />20.98<br />Filter by price increase > 10%: Where(w => PriceIncrease(w) > .1)<br />
  68. 68. Reduce<br />MSFT<br />INTC<br />27.96<br />31.21<br />Reduce to a single stream: Merge()<br />
  69. 69. Done!<br />27.96<br />31.21<br />
  70. 70. from tick instockTicks<br />group tick bytick.SymbolintosymbolStream<br />from window insymbolStream.Buffer(2, 1)<br />let increase = PriceIncrease(window)<br />where increase > .1<br />select new { symbol = symbolStream.Key, increase }; <br />LINQ: Event Processing<br />source<br />group<br />aggregate<br />apply<br />filter<br />reduce<br />
  71. 71. Change MainForm.Query to compute the Average High and Average Low over the past 5 trading days as well as the current Close and Date<br />Challenge: Event Processing<br />
  72. 72. Answer<br />
  73. 73. Reactive coincidence<br />streaming windows<br />
  74. 74. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  75. 75. Event Duration<br />0<br />2<br />1<br />vs<br />0<br />2<br />1<br />
  76. 76. An Example<br />left <br />left<br />right<br />
  77. 77. Representing Duration<br />begin<br />begin<br />end<br />end<br />Window<br />
  78. 78. Store<br />
  79. 79. Reactive Coincidence<br />Which people are at the store while it is opened?<br />5/5<br />5/6<br />curley<br />moe<br />larry<br />
  80. 80. Reactive Coincidence<br />Which people are at the store while it is opened?<br />5/5<br />5/6<br />moe<br />larry<br />curley<br />moe<br />
  81. 81. LINQ Join<br />from opening instoreOpenings<br />join person inpersonArrives<br />onopening.Closeequalsperson.Leavesinto g<br />selectnew { opening.Day, People = g };<br />
  82. 82. Change query in MainForm.MainForm to compute a stream of deltas when the mouse is down<br />Challenge: Drag and Drop<br />
  83. 83. Answer<br />
  84. 84. Programming the cloud<br />a glimpse into the future<br />
  85. 85. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  86. 86. Distributed Queries<br />Cloud<br />results<br />query<br />
  87. 87. Observable.Timer(<br />TimeSpan.FromSeconds(1),<br />Scheduler.Azure)<br /> .ObserveLocally()<br /> .Subscribe(Console.WriteLine);<br />Distributed Queries<br />Send the query to the cloud<br />Send the results back<br />
  88. 88. Pass-by-Value<br /> [Serializable] classMyType { … }<br />Pass-by-Reference<br />classMyType : MarshalByRefObject{ … }<br />Distributed Parameters<br />
  89. 89. var x = 42;<br />scheduler.Schedule(() =><br />Console.WriteLine(x));<br />classClosure {<br />public intx;<br />public void M() {<br />Console.WriteLine(x);<br /> }<br />}<br />var closure = newClosure();<br />closure.x = 42;<br />scheduler.Schedule(closure.M);<br />Distributed Scheduling<br />Pass by value or reference?<br />
  90. 90. interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state, Action<T> work);<br /> …<br />}<br />Scheduler Interface Revisited<br />
  91. 91. var x = 42;<br />scheduler.Schedule(<br /> x,<br /> state =><br />Console.WriteLine(state));<br />static void M(int state) {<br />Console.WriteLine(state);<br />}<br />varx = 42;<br />scheduler.Schedule(<br /> x,<br /> M);<br />Distributed Scheduling<br />No closures!!!<br />
  92. 92. scheduler.Schedule(42, x =><br />scheduler.Schedule(x + 1, y =><br />Console.WriteLine(y)));<br />Nested Scheduling<br />
  93. 93. Distributed Scheduling<br />cloud<br />Scheduler<br />
  94. 94. interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state,<br /> Action<IScheduler, T> work);<br /> …<br />}<br />Scheduler Interface Rerevisited<br />
  95. 95. scheduler.Schedule(42, (s, x) =><br />s.Schedule(x + 1, y =><br />Console.WriteLine(y)));<br />Nested Scheduling<br />
  96. 96. Fan-out Scheduling<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />Scheduler<br />
  97. 97. var d = scheduler.Schedule(42, (s, x) => {<br />var d1 = s.Schedule(x + 1, Console.WriteLine);<br />var d2 = s.Schedule(x + 2, Console.WriteLine);<br />});<br />Fan-out Scheduling<br />How do we make d depend on d1 & d2?<br />
  98. 98. interfaceIScheduler {<br /> …<br />IDisposable Schedule<T>(T state,<br />Func<IScheduler, T, IDisposable> work);<br /> …<br />}<br />Scheduler Interface Rererevisited<br />
  99. 99. var d = scheduler.Schedule(42, (s, x) => {<br />var d1 = s.Schedule(x + 1, Console.WriteLine);<br />vard2 = s.Schedule(x + 2, Console.WriteLine);<br /> return newCompositeDisposable(d1, d2);<br />});<br />Fan-out Scheduling<br />
  100. 100. scheduler.Schedule(42, (state, self) =><br /> {<br />Console.WriteLine(state);<br /> self(state + 1); });<br />Easy Recursive Scheduling<br />
  101. 101. Change Program.Main to use the AppDomainScheduler<br />ReimplementGenerateObservable.Subscribe<br />Challenge: AppDomains<br />
  102. 102. Answer<br />
  103. 103. Continuations Everywhere<br />continuation-passing style used elsewhere<br />
  104. 104. Ruby<br />1..10.each do |x| puts x * xend<br />
  105. 105. AJAX<br />$.ajax({<br /> url: 'http://en.wikipedia.org/w/api.php',<br />dataType: 'jsonp',<br />data: {<br /> action: 'opensearch',<br /> search: term,<br /> format: 'json'<br /> },<br />success: function(msg) {<br /> alert('Data saved:' + msg);<br />}<br />});<br />
  106. 106. node.js<br />var net = require('net');<br />var server = net.createServer(function (socket) {<br />socket.write("Echo serverrn"); socket.pipe(socket);<br />});<br />server.listen(1337, "127.0.0.1");<br />
  107. 107. Challenge<br />Using Rx, build a TCP server that works in a similar manner to node.js.<br />
  108. 108. The Reactive Extensions<br />Rx is …<br />a set of types representing asynchronous data streams<br />a set of operators to query asynchronous data streams<br />a set of types to parameterize concurrency<br />Rx = Observables + LINQ + Schedulers<br />
  109. 109. Learn More<br />Resources<br />Rx Developer Center<br />Rx on Channel 9<br />Projects<br />ReactiveUI<br />Fluent State Observer<br />Reactive ETL<br />ReactiveOAuth<br />Reactive Remoting<br />Extensions to the Extensions<br />Reactive Extensions – Extensions<br />Rx Contrib<br />RxUtilities<br />Rx Power Toys<br />

×