Reactive Extensions (Rx) Your prescription to cure event processing blues Bart J.F. De Smet Software Development Engineer bartde@microsoft.com
Why should I care? GPS RSS feeds Social media Server management
Event Processing Systems �� ����� � ������� �� ◦ ����� � ������� Way simpler with Rx �������������������� ������������������������������ �������������������� �������������������� ���������� ���������� ���������� ���������������������� ���������������������� ���������������������� ����������������������� ������ � � ����� ����� ����� ��������������� ��������������� ��������������� �������������������������� ����������� �������������������� ����������� ��������� ���������� ��������� � � � Queries! LINQ! � .NET 3.5 SP1, 4.0, and 4.5 � Silverlight 4, and 5 � Windows Phone 7 and 7.5 � JavaScript (RxJS) Download at MSDN Data Developer Center or use NuGet
Observable Sequences Mathematical Dual of IEnumerable<T> interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } interface IObserver<in T> { void On Next(T value); void On Error(Exception ex); void On Completed(); }
Push-Based Data Retrieval Application Interactive MoveNext Reactive Got next? OnNext Have next! IObservable<T> IEnumerable<T> IObserver<T> IEnumerator<T> �����������
DEMO The IObservable<T> interface
Creating Observable Sequences OnNext * [ OnError | OnCompleted ] Observable.Never<int>() ����������� Observable.Empty<int>() ���������� Observable.Return<int>(42) ����������� Observable.Throw<int>(ex)
Generator Functions var e = new IEnumerable<int> { var o = Observable.Generate( for (int i = 0; 0, i < 10; i => i < 10, i++) i => i + 1, yield return i * i; i => i * i }; ); ������������ ����������� o.Subscribe(x => { foreach (var x in e) { Console.WriteLine(x); Console.WriteLine(x); } });
The Create operator Observable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted(); return () => { /* unsubscribe action */ }; }); IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); } ); ���������������� �������������������� ������������� �������������� ������������������������ ���������������� ������������������������������������
The Create operator Observable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted(); return () => { /* unsubscribe action */ }; }); IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); } ); Thread.Sleep(30000); ���
The Create operator Observable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted(); return () => { /* unsubscribe action */ }; }); IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); } ); Thread.Sleep(30000); ���
The Create operator Observable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted(); return () => { /* unsubscribe action */ }; }); IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); } ); Thread.Sleep(30000); ��
The Create operator Observable<int> o = Observable.Create<int>(observer => { // Assume we introduce concurrency (see later)… observer.OnNext(42); observer.OnCompleted(); return () => { /* unsubscribe action */ }; }); ����������� ������� IDisposable subscription = o.Subscribe( onNext: x => { Console.WriteLine("Next: " + x); }, onError: ex => { Console.WriteLine("Oops: " + ex); }, onCompleted: () => { Console.WriteLine("Done"); } ); Thread.Sleep(30000);
DEMO Creating observable sequences
The Trouble with .NET Events ������������������� ������������������ ��������������� ���������� ���������������� ���������� ���������� ���������� ���� ���� �� � ���������������� �� ���������������� � � � � � ���� ��!�"���������������#�������� $% ��!��"������������ ����������������& & & &� � � � �'�(#��������#���)�'� #��������������������
Observable Sequences are First-Class Objects �'(���������'�������� $�������"�%�����&����� �*+�����+!� �*+�����+!�, �*+�����+!� �*+�����+!� , , ,-���� -����� -���� -���� � � ���������� �� � *+�����+!��.���/���� *+�����+!��.���/���������� " ��������� " �% *+�����+!��.���/���� *+�����+!��.���/���� ��� ��!������������������ �0#���� �0#���� �0#����1�� ���1���� ���1����� �0#���� � � �% ������"������������� ��� ��+����1���������!������2�+����+��3�% ��+����1�����4��1��� �4��1��� �4��1��� �4��1����� �� �� ��% #�������������������)
Other Conversions with IObservable<T> � Asynchronous Programming Model (APM) � Legacy support; prefer going through Task<T> .���,������*+�����+!�,���������1���5�6�� �� *+�����+!��.���5�6��-������ �.���5�6��-�����������7����8��1���� �.���5�6��-������ �.���5�6��-������ ����/��8��1����% � Task<T> � Way to represent single-value asynchrony 9��",��������#��!9��" �� (�+8!�����4�(�!���2�����9��"5�6������� � � � �9�*+�����+!� 9�*+�����+!� 9�*+�����+!��� 9�*+�����+!� �� �� ��% � IEnumerable<T> � Pull-to-push conversion But where does the enumeration happen? �*+�����+!�,��������9�:��� �� /������+!��;�����<���<� � � �9�*+�����+!� � 9�*+�����+!� 9�*+�����+!� 9�*+�����+!��� �� �� ��%
Recommend
More recommend