SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
Как приручить реактивное
программирование
Денис Цветцих
Ice Rock Dev
icerockdev.com
12-я конференция .NET разработчиков
15 мая 2016
dotnetconf.ru
2
Кто я?
• 7+ лет .NET
• Разработка корпоративных приложений
• Люблю хипстерские библиотеки 
3
Почему я здесь?
• 6 лет назад приручил Rx
• 3 года назад приручил ReactiveUI
• С тех пор активно использую в XAML
проектах
4
Многие не используют
• Не знают о Rx и ReactiveUI
• Находятся под влиянием «мифов» о
реактивном программировании
5
О чем мы поговорим?
• Что такое реактивное программирование?
• Для каких задач его использовать?
• Развеем мифы, которые мешают его
использовать
6
Опрос
• Кто не знает, что такое реактивное
программирование?
• Кто знаком с Rx и ReactiveUI, но не решился
использовать в своих проектах?
• Кто использовал Rx или ReactiveUI на
продакшене?
ЧТО ТАКОЕ РЕАКТИВНОЕ
ПРОГРАММИРОВАНИЕ
8
Что такое реактивное
программирование?
Реактивное программирование –
это парадигма программирования,
ориентированная на потоки данных и
распространение изменений.
(Википедия)
9
Парадигма программирования
Парадигма программирования –
это система идей и понятий, определяющих
стиль написания компьютерных программ.
10
Императивная программа
var A = 10;
var B = A + 1;
// Чему равно В?
11
A = A + 1;
// А теперь чему равно В?
11
11
Реактивная программа
var A = 10;
var B <- A + 1;
<- оператор «судьбы»
// Чему равно В?
11
A = A + 1;
// А теперь чему равно В?
12
12
Реактивное программирование
Реактивное программирование – это
парадигма программирования,
ориентированная на потоки данных и
распространение изменений.
Потоки данных – последовательность значений
каждой переменной или свойства класса.
Распространение изменений – уведомления
«заинтересованных» об изменениях.
13
Pull
Pull – класс A взаимодействует с
классом B и вытягивает из него
необходимые данные
Class A Class B
GetData()
Interacts with
14
Push
Push – класс B самостоятельно
выталкивает данные, как только они
становятся доступны.
Class A
ProcessData()
Class BReacts on
15
Примеры из жизни
• Вычислимые ячейки Excel
• Принцип Голливуда – «Не звоните нам,
мы сами вам позвоним»
• Push - уведомления
РЕАКТИВНОЕ ПРОГРАММИРОВАНИЕ НА C#
17
Прошлое реактивного
программирования на C#
• Bindable Linq
• https://bindablelinq.codeplex.com
• 1.0 beta 1
• Последний коммит 5 окт 2008
• Continuous LINQ
• http://clinq.codeplex.com/
• 2.2.0.1
• Последний коммит 23 июня 2010
• Obtics
• https://obtics.codeplex.com/
• 1.0.13.0
• Последний коммит 11 июня 2011
18
Настоящее
• Reactive Extensions (Rx)
• Эрик Мейер из MS Research
• ReactiveUI
• библиотека на базе Rx для создания
элегантных UI для всех XAML платформ
19
Внутри .NET
public interface IObservable<T>
{
IDisposable Subscribe(IObserver<T> observer);
}
public interface IObserver<T>
{
void OnNext(T value);
void OnCompleted();
void OnError(Exception error);
}
20
Оператор судьбы через Rx
var A = new Subject<int>();
// B <- A + 3
var B = A.Select(a => a + 3);
// C <- A * B
var С = A.Zip(B, (a, b) => a * b);
A.OnNext(1);
21
Observable.Select – проекция
22
Observable.Merge – слияние
23
Observable.Zip - объединение
КАКИЕ ЗАДАЧИ МОЖНО РЕШАТЬ
25
Пример - LoginViewModel
public class LoginViewModel //: INotifyPropertyChanged
{
public string Login { get; set; } // PropertyChanged
public string Password { get; set; } // PropertyChanged
public ICommand LoginCommand { get; private set; }
private Task OnLogin()
{
}
}
26
1. Подписка на изменение свойства
// Подписка
IDisposable _subscription =
this.ObservableForProperty(vm => vm.Login)
.Subscribe(OnLoginChanged);
// Реакция на событие
private void OnLoginChanged
(IObservedChange<LoginViewModel, String> change)
{
}
// Отписка
_subscription.Dispose();
27
2. Подписка на изменение нескольких
свойств
IDisposable _subscription =
this.WhenAny(
vm => vm.Login,
vn => vm.Password,
(login, password) =>
!string.IsNullOrEmpty(login.Value) &&
!string.IsNullOrEmpty(password.Value))
.Subscribe(OnCredentialsChanged);
28
3. Реактивная асинхронная команда
CanExecute – false, когда
1) Не выполняется условие отправки запроса
2) Выполняется асинхронный запрос
29
3. Реактивная асинхронная команда
LoginCommand = ReactiveCommand.CreateAsyncTask
(canExecute,
async _ => await _loginService.Login(Login, Password));
LoginCommand.Subscribe(OnLoginCompleted);
} // of ctor
private void OnLoginCompleted(bool loginSuccessed)
{
}
30
Достоинства ReactiveCommand
• Не нужно мониторить значения свойств
Login и Password
• Не нужно мониторить начало и конец
асинхронной операции логина
31
Что ещё умеет ReactiveUI
• Навигация ViewModel First
• Маппинг View и ViewModel ручной
• IoC на основе Splat
• Валидация (не в фреймворке, в сэмплах)
• Есть плагин для Fody, который генерит INPC
Но все равно как MVVM фреймворк ReactiveUI
слабоват
Поэтому используем из него только команды и
привязки
32
Книга мифов о ReactiveUI
33
1. Rx – это экзотическая
функциональщина (F#, Scala, Haskel)
F#
Scala
34
На самом деле
• Интерфейсы IObservable и IObserver
входят в состав .NET
• Для C# существует несколько библиотек
от BindableLinq до ReactiveUI
35
2. Реактивное программирование –
это backend
36
Rx для UI маленький, да удаленький
Что ещё ReactiveUI:
• ReactiveCommand
• ObservableForProperty
• WhenAny
37
3. Боюсь использовать ReactiveUI,
слишком экзотично
38
Недостатки ReactiveUI
• IoC привязан к Splat
• Есть MessageBus, без которого можно
обойтись
• Неудобная для WinRT и UWP навигация
ViewModelFirst
39
Используем совместно с другим
MVVM
Используем сильные стороны:
• ReactiveCommand
• Привязки на уровне ViewModel
(ObservableForProperty и WhenAny)
Не используем слабые стороны:
• Навигация
• IoC
40
4. Использовать несколько MVVM на
одном проекте нельзя!
41
Можно, только осторожно 
• Каждому MVVM – своя область
ответственности
• Контроль, чтобы эта область не
расползалась (регулярные ревью)
42
Наш опыт
ReactiveUI Mugen Prism
ReactiveCommand
ObservableForProperty
WhenAny
XAML Bindings
Composite UI
43
Подведем итоги
• ReactiveUI можно (и нужно ) использовать:
• Реактивные команды
• Привязки на уровне ViewModel вместо
MessageBus
• ReactiveUI используем как дополнение к
любимому MVVM фреймворку
44
Реактивное программирование –
не страшный и загадочный зверь
45
А верный друг на ваших проектах!
46
Что дальше делать?
• Познакомиться: скачать Rx или ReactiveUI,
посмотреть сэмплы
• Отладить приложение для Codefest,
сообщество будет вам благодарно
• Попробовать Rx и ReactiveUI на
продакшене
47
Полезные ссылки
Классное видео для начинающих
https://vimeo.com/43172610
Про Rx для разных языков программирования
http://reactivex.io/
Официальная страница
http://reactiveui.net/
Код, примеры
https://github.com/reactiveui
Autofac
https://github.com/alexeyzimarev/RxUI6WithAutofac
48
Спасибо за внимание
Денис Цветцих
den.tsvettsih@yandex.ru

Weitere ähnliche Inhalte

Was ist angesagt?

Иван Крутов - Автоматизация сборки Java-проекта
Иван Крутов - Автоматизация сборки Java-проектаИван Крутов - Автоматизация сборки Java-проекта
Иван Крутов - Автоматизация сборки Java-проекта
Yandex
 
Мастер класс- Maven + Jenkins
Мастер класс- Maven + JenkinsМастер класс- Maven + Jenkins
Мастер класс- Maven + Jenkins
Valentin Fedoskin
 
Быстрое прототипирование системы управления БПЛА
Быстрое прототипирование системы управления БПЛАБыстрое прототипирование системы управления БПЛА
Быстрое прототипирование системы управления БПЛА
CEE-SEC(R)
 

Was ist angesagt? (20)

Continuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedContinuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons Learned
 
"Electron. How the most modern framework works" Oleksii Holubiev
"Electron. How the most modern framework works" Oleksii Holubiev"Electron. How the most modern framework works" Oleksii Holubiev
"Electron. How the most modern framework works" Oleksii Holubiev
 
Как Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QAКак Cluster Membership Software может помочь QA
Как Cluster Membership Software может помочь QA
 
Cистемы автоматической сборки проектов (Полина Фоминых)
Cистемы автоматической сборки проектов (Полина Фоминых)Cистемы автоматической сборки проектов (Полина Фоминых)
Cистемы автоматической сборки проектов (Полина Фоминых)
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
 
Иван Крутов - Автоматизация сборки Java-проекта
Иван Крутов - Автоматизация сборки Java-проектаИван Крутов - Автоматизация сборки Java-проекта
Иван Крутов - Автоматизация сборки Java-проекта
 
Python Development process in Yandex
Python Development process in YandexPython Development process in Yandex
Python Development process in Yandex
 
Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)Python tools for web development (Python meetup Almaty #ALAPY)
Python tools for web development (Python meetup Almaty #ALAPY)
 
"Prom.ua shopping cart workflow as a microfrontend", Danylo Kazymyrov
"Prom.ua shopping cart workflow as a microfrontend", Danylo Kazymyrov"Prom.ua shopping cart workflow as a microfrontend", Danylo Kazymyrov
"Prom.ua shopping cart workflow as a microfrontend", Danylo Kazymyrov
 
Мастер класс- Maven + Jenkins
Мастер класс- Maven + JenkinsМастер класс- Maven + Jenkins
Мастер класс- Maven + Jenkins
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
 
course js day 1
course js day 1course js day 1
course js day 1
 
Быстрое прототипирование системы управления БПЛА
Быстрое прототипирование системы управления БПЛАБыстрое прототипирование системы управления БПЛА
Быстрое прототипирование системы управления БПЛА
 
My talk on Docker from Moscow Django Meetup #25
My talk on Docker from Moscow Django Meetup #25My talk on Docker from Moscow Django Meetup #25
My talk on Docker from Moscow Django Meetup #25
 
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
 
Введение в maven
Введение в mavenВведение в maven
Введение в maven
 
"Доклад не про React", Антон Виноградов, MoscowJS 27
"Доклад не про React", Антон Виноградов, MoscowJS 27"Доклад не про React", Антон Виноградов, MoscowJS 27
"Доклад не про React", Антон Виноградов, MoscowJS 27
 
Иван Кожин «Saritasa Tools или ещё один подход к архитектуре приложения»
Иван Кожин «Saritasa Tools или ещё один подход к архитектуре приложения»Иван Кожин «Saritasa Tools или ещё один подход к архитектуре приложения»
Иван Кожин «Saritasa Tools или ещё один подход к архитектуре приложения»
 

Andere mochten auch

Situacion problematica
Situacion problematicaSituacion problematica
Situacion problematica
analauramarzo3
 
Situacion problematica
Situacion problematicaSituacion problematica
Situacion problematica
analauramarzo3
 
Group06_Final FEA
Group06_Final FEAGroup06_Final FEA
Group06_Final FEA
Sonny Pham
 
Presentacion equipo ecológico
Presentacion equipo ecológico Presentacion equipo ecológico
Presentacion equipo ecológico
mjgp12109595
 
Prescantinflas
PrescantinflasPrescantinflas
Prescantinflas
19892020
 

Andere mochten auch (16)

Как приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложенияхКак приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложениях
 
Situacion problematica
Situacion problematicaSituacion problematica
Situacion problematica
 
Yeni prespektifler çalıştayı
Yeni prespektifler çalıştayı Yeni prespektifler çalıştayı
Yeni prespektifler çalıştayı
 
5derecho informatico
5derecho informatico5derecho informatico
5derecho informatico
 
Situacion problematica
Situacion problematicaSituacion problematica
Situacion problematica
 
Brochure
BrochureBrochure
Brochure
 
Que Sera Sera sdec15
Que Sera Sera sdec15Que Sera Sera sdec15
Que Sera Sera sdec15
 
Electrojemel
ElectrojemelElectrojemel
Electrojemel
 
04 8996
04 899604 8996
04 8996
 
Dijital Dünya Bilgilendirme Sunumu
Dijital Dünya Bilgilendirme SunumuDijital Dünya Bilgilendirme Sunumu
Dijital Dünya Bilgilendirme Sunumu
 
Group06_Final FEA
Group06_Final FEAGroup06_Final FEA
Group06_Final FEA
 
Как приручить реактивное программирование
Как приручить реактивное программированиеКак приручить реактивное программирование
Как приручить реактивное программирование
 
Presentacion equipo ecológico
Presentacion equipo ecológico Presentacion equipo ecológico
Presentacion equipo ecológico
 
11.cynthia caro diagrama de circulo de la naturaleza
11.cynthia  caro diagrama de circulo de la naturaleza11.cynthia  caro diagrama de circulo de la naturaleza
11.cynthia caro diagrama de circulo de la naturaleza
 
Prescantinflas
PrescantinflasPrescantinflas
Prescantinflas
 
“Common ways to improve performance & data storage”., Сергей Сыроватченко, De...
“Common ways to improve performance & data storage”., Сергей Сыроватченко, De...“Common ways to improve performance & data storage”., Сергей Сыроватченко, De...
“Common ways to improve performance & data storage”., Сергей Сыроватченко, De...
 

Ähnlich wie Как приручить реактивное программирование

2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
HappyDev
 
Javascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только одинJavascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только один
Sergey Xek
 
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Ontico
 
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только одинSECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON
 
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальность
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальностьДенис Измайлов, JavaScript сегодня: React, Redux и новая реальность
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальность
ScrumTrek
 
JavaScript сегодня: React, Redux и новая реальность
JavaScript сегодня: React, Redux и новая реальностьJavaScript сегодня: React, Redux и новая реальность
JavaScript сегодня: React, Redux и новая реальность
Denis Izmaylov
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrus
Alex Chistyakov
 

Ähnlich wie Как приручить реактивное программирование (20)

2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
 
Javascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только одинJavascript-фреймворки:
 должен остаться только один
Javascript-фреймворки:
 должен остаться только один
 
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
Javascript-фреймворки: должен остаться только один / Аверин Сергей (Acronis)
 
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только одинSECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
SECON'2016. Сергей Аверин. Javascript-фреймворки:
 должен остаться только один
 
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только одинSECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
SECON'2016. Аверин Сергей, Javascript-фреймворки:
 должен остаться только один
 
Введение в redux
Введение в reduxВведение в redux
Введение в redux
 
React новая эра фронтенд разработки / Роберт Харитонов (Liberty Global)
React новая эра фронтенд разработки / Роберт Харитонов (Liberty Global)React новая эра фронтенд разработки / Роберт Харитонов (Liberty Global)
React новая эра фронтенд разработки / Роберт Харитонов (Liberty Global)
 
Денис Чистяков — JavaScript на фронте и в тылу
Денис Чистяков — JavaScript на фронте и в тылуДенис Чистяков — JavaScript на фронте и в тылу
Денис Чистяков — JavaScript на фронте и в тылу
 
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
 
SECON'2016. Мухаметов Андрей, RxSwift && Apple TV - так ли хорошо всё новое?
SECON'2016. Мухаметов Андрей, RxSwift && Apple TV - так ли хорошо всё новое?SECON'2016. Мухаметов Андрей, RxSwift && Apple TV - так ли хорошо всё новое?
SECON'2016. Мухаметов Андрей, RxSwift && Apple TV - так ли хорошо всё новое?
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтенда
 
Евгений Ртищев "Мобильная платформа на ReactNative"
Евгений Ртищев "Мобильная платформа на ReactNative"Евгений Ртищев "Мобильная платформа на ReactNative"
Евгений Ртищев "Мобильная платформа на ReactNative"
 
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальность
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальностьДенис Измайлов, JavaScript сегодня: React, Redux и новая реальность
Денис Измайлов, JavaScript сегодня: React, Redux и новая реальность
 
JavaScript сегодня: React, Redux и новая реальность
JavaScript сегодня: React, Redux и новая реальностьJavaScript сегодня: React, Redux и новая реальность
JavaScript сегодня: React, Redux и новая реальность
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrus
 
Дикие микросервисы на JUG Екатеринбург
Дикие микросервисы на JUG ЕкатеринбургДикие микросервисы на JUG Екатеринбург
Дикие микросервисы на JUG Екатеринбург
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
A.pleshkov
A.pleshkovA.pleshkov
A.pleshkov
 
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"
 

Mehr von DotNetConf

Mehr von DotNetConf (13)

Как грабить корованы
Как грабить корованыКак грабить корованы
Как грабить корованы
 
Делаем очередь поверх Кассандры
Делаем очередь поверх КассандрыДелаем очередь поверх Кассандры
Делаем очередь поверх Кассандры
 
К искусству записи пользовательских историй
К искусству записи пользовательских историйК искусству записи пользовательских историй
К искусству записи пользовательских историй
 
Кроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и противКроссплатформенная библиотека для Android и iOS: за и против
Кроссплатформенная библиотека для Android и iOS: за и против
 
Быстрый бэкенд с parse.com
Быстрый бэкенд с parse.comБыстрый бэкенд с parse.com
Быстрый бэкенд с parse.com
 
Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?Kotlin в production. Как и зачем?
Kotlin в production. Как и зачем?
 
Платформа Apache Hadoop
Платформа Apache HadoopПлатформа Apache Hadoop
Платформа Apache Hadoop
 
Робототехника для прикладных программистов
Робототехника для прикладных программистовРобототехника для прикладных программистов
Робототехника для прикладных программистов
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
 
Inversion of Control в .NET
Inversion of Control в .NETInversion of Control в .NET
Inversion of Control в .NET
 
Введение в реактивный .NET
Введение в реактивный .NETВведение в реактивный .NET
Введение в реактивный .NET
 
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
Особенности передачи и обработки видео данных. Приправа из кодеков или с чем ...
 
Машинное обучение на платформе .NET
Машинное обучение на платформе .NETМашинное обучение на платформе .NET
Машинное обучение на платформе .NET
 

Как приручить реактивное программирование