reactive extensions
DESCRIPTION
Введение в реактивные расширения.Видео доклада: http://getdev.net/Event/reactive-extensionsTRANSCRIPT
![Page 1: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/1.jpg)
Реактивные расширения
Сергей ЗвягинIngate Development
Специально для GetDev.NET
для чайников
![Page 2: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/2.jpg)
Реактивное программирование
• Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что выполняемая модель должна автоматически распространять изменения сквозь поток данных.
http://ru.wikipedia.org/wiki/Реактивное_программирование
![Page 3: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/3.jpg)
Push и Pull
• Существует 2 подхода обработки последовательности данных
• При push-подходе цель запрашивает у источника содержимое
• При pull-подходе источник информирует цель о наличии данных
![Page 4: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/4.jpg)
Push-подход
• Чтение из файла• Суммирования элементов массива• Обработка выборки из БД
![Page 5: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/5.jpg)
Pull-подход
• Обработка действий пользователя• Получение данных от веб-сервиса• Таймеры• Анимация пользовательского интерфейса
![Page 6: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/6.jpg)
Push-подход
• Push-коллекции в .NET реализуются с использованием интерфейсов IEnumerable<T> и IEnumerator<T>
• Это могут быть коллекции в памяти (списки, массивы), бесконечные последовательности (генераторы) или наборы данных с неизвестным заранее размером (выборка из БД)
• LINQ позволяет быстро организовать работу с такими коллекциями
![Page 7: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/7.jpg)
Pull-подход
• События и делегаты• Асинхронные методы BeginXXXX и EndXXXX• async/await• Сторонние реализации• Да и зачем тут LINQ?
![Page 8: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/8.jpg)
Типичные задачи
• Как обработать двойной клик?• А тройной клик?• Как проверять орфографию в словах,
которые вводит пользователь в поле?• Когда делать запросы в базу при
реализации элемента управления «живой поиск»?
![Page 9: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/9.jpg)
Pull-подход
• В .NET 4 появилось 2 новых интерфейса, реализующих pull-подход - IObservable<T> и IObserver<T>
![Page 10: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/10.jpg)
Простой пример
• Push-коллекция
• Pull-коллекция
![Page 11: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/11.jpg)
.NET Rx сборки
• System.CoreEx• System.Interactive• System.Observable• System.Reactive• System.Threading
![Page 12: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/12.jpg)
Реактивные расширения
• Представление асинхронных потоков данных как Observable
• Формирование запросов с помощью LINQ• Параметризация конкурентных
асинхронных потоков с помощью Schedulers
• Rx = Observables + LINQ + Schedulers
![Page 13: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/13.jpg)
Операторы LINQ
• Примитивы• Создание последовательностей• Конвертация• Комбинация• Математические операции• Временные операции• Фильтрация и выбор• Обработка исключений• Функциональные операции• Специальные операции
![Page 14: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/14.jpg)
Примитивы
• Never• Empty• Return• Throw
![Page 15: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/15.jpg)
Создание последовательностей
• Create• Generate• Defer• Range
![Page 16: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/16.jpg)
Конвертация
• FromAsyncPattern• FromEvent• FromEventPattern• ToObservable• ToEnumerable
![Page 17: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/17.jpg)
Комбинация
• Amb• Concat• StartWith• Merge• Repeat• Zip
![Page 18: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/18.jpg)
Математические операции
• Aggregate• Count• Min• Max• Sum
![Page 19: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/19.jpg)
Временные операции
• Delay• Interval• TimeInterval• Timestamp• Timeout
![Page 20: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/20.jpg)
Фильтрация и выбор
• Take• TakeUntil/TakeWhile• Select• SelectMany• Skip• SkipUntil/SkipWhile
![Page 21: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/21.jpg)
Обработка исключений
• Catch• Finally• Retry• OnErrorResumeNext
![Page 22: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/22.jpg)
Функциональные операции
• Let• Prune• Publish• Replay
![Page 23: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/23.jpg)
Специальные операции
• Do• Run• Remotable
![Page 24: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/24.jpg)
Многопоточность
• В каком потоке будет обрабатываться результирующая функция?– В текущем потоке– В новом потоке– В тредпуле– В потоке интерфейса
![Page 25: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/25.jpg)
Schedulers
• Для управления конкурентными асинхронными потоками используются объекты, реализующие интерфейс IScheduler
• По умолчанию используется наиболее подходящий Scheduler
• Можно принудительно указать, какой Scheduler будет использоваться в конкретном случае
![Page 26: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/26.jpg)
Scheduler по умолчанию
• Небольшое количество событий – ImmediateScheduler
• Большое или неопределенное количество событий – CurrentThreadScheduler
• При использовании таймеров - ThreadPoolScheduler
![Page 27: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/27.jpg)
Использование Scheduler
• Используются статические свойства класса System.Reactive.Concurrency.Scheduler
• Указать Scheduler можно либо параметром в перегруженном методе оператораObservable.Timer(Timespan.FromSeconds(0.01), Scheduler.DispatcherScheduler).Subscribe(…);
• Либо с использованием специального оператора ObserveOnObservable.Timer(Timespan.FromSeconds(0.01)) .ObserveOn(Scheduler.DispatcherScheduler) .Subscribe(…);
![Page 28: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/28.jpg)
Пример запросаObservable.FromEvent<TextChangedEventArgs> (searchTextBox, "TextChanged") .Select(e => ((TextBox)e.Sender).Text) .Where(text => text.Length > 2) .Do(s => searchResults.Opacity = 0.5) .Throttle(TimeSpan.FromMilliseconds(400)) .ObserveOnDispatcher() .Do(s => Indicator.Visibility = Visibility.Visible) .SelectMany(txt => searchTwitter(txt)) .Select(searchRes => ParseTwitterSearch(searchRes)) .ObserveOnDispatcher() .Do(s => Indicator.Visibility = Visibility.Collapsed) .Do(s => searchResults.Opacity = 1) .Subscribe(tweets => searchResults.ItemsSource = tweets);
![Page 29: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/29.jpg)
Где можно использовать?
• .NET Framework 3.5 SP1• .NET Framework 4• Silverlight 4• Silverlight 5• Windows Phone 7• Windows Phone 7.1 “Mango”• .NET Framework 4.5 + WinRT (Experimental)• JavaScript
![Page 30: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/30.jpg)
JavaScript
• Библиотека RxJS доступна в экспериментальной версии
• Логика работы повторяет логику Rx .NET• Bridges – дополнительные конвертеры
![Page 31: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/31.jpg)
Bridges
• FromDOMEvent
var canvas = document.getElementById("canvas");var source = Rx.Observable.FromDOMEvent(canvas, "mousemove");
source.Subscribe(function(ev) { // Handle the mousemove event here});
![Page 32: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/32.jpg)
Bridges
• FromJQuery
Rx.Observable.FromJQuery($("div, span"), "click") .Subscribe(function(evt) { $("position").html("Mouse at " + evt.pageX + ", " + evt.pageY); });
![Page 33: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/33.jpg)
Bridges
• XmlHttpRequest
function searchWikipedia(term) { var url = "http://en.wikipedia.org/w/api.php" + "?action=opensearch&search=" + term + "&format=json";
return Rx.Observable.XmlHttpRequest(url) .Select(function(result) { var response = eval(result.responseText); if (response.length == 2) return response[1]; else return []; });}
![Page 34: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/34.jpg)
Пример запросаvar input = $("#searchInput");var words = input.ToObservable("keyup") .Select(function(_) { return input.val(); }) .Throttle(500) .DistinctUntilChanged() .Select(function(term) { return search(term); }) .Switch();words.Subscribe(function(data) { $("#results").empty(); $.each(data, function(_, value) { $("#results").append("<li>" + value + "</li>"); }});
![Page 35: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/35.jpg)
ВОПРОСЫ?На этом всё…
![Page 36: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/36.jpg)
Полезные ссылки
• Reactive Extensions Developer Center http://msdn.microsoft.com/en-us/data/gg577609
• Reactive Framework Wiki http://rxwiki.wikidot.com/
• Rx Team Blog http://blogs.msdn.com/b/rxteam/
• Скачать Rx http://msdn.microsoft.com/en-us/data/gg577610
![Page 37: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/37.jpg)
Следующая встреча
![Page 38: Reactive Extensions](https://reader036.vdocuments.site/reader036/viewer/2022062704/555e1babd8b42a9e188b5995/html5/thumbnails/38.jpg)
Если будут ещё вопросы – пишите!Сергей Звягин, Ingate Development• E-mail: [email protected]• Twitter: @Bingo87• Xbox: BingoRUS
Специально для GetDev.NET
Спасибо за внимание!