SlideShare uma empresa Scribd logo
1 de 44
Reactive Extensions
Сергей Тепляков
STeplyakov@luxoft.com
О Вашем инструкторе


 Сергей Тепляков
 Visual C# MVP, RSDN Team member
 Sergey.Teplyakov@gmail.com
 SergeyTeplyakov.blogspot.com




                                    1-2
Необходимая подготовка
Слушатели должны:

 Быть знакомы с основами языка C#
  и платформы .Net
 Обладать базовыми знаниями
  многопоточности
 Быть знакомы с LINQ (Language
  Integrated Query)


                                     1-4
Roadmap

   Введение в реактивные расширения
   Дуализм интерфейсов
   Основы Rx
   Observable sequences
   Events и Observables
   Observables и асинхронные операции
   Concurrency
   Новости из Редмонта
                                         1-5
Интерактивная и реактивная
модель
Реактивное программирование

Парадигма программирования, ориентированная на потоки
данных и распространение изменений. Это означает, что
должна    существовать   возможность   легко    выражать
статические и динамические потоки данных, а также то, что
выполняемая модель должна автоматически распространять
изменения сквозь поток данных.

http://ru.wikipedia.org/
/wiki/Реактивное_программирование
Реактивная модель

"Принцип Голливуда" – "Не звоните нам, мы сами вам
позвоним"

(Hollywood Principle - Don't call us, we'll call you)
Rx - это

1. набор классов, представляющих собой асинхронный
поток данных
2. набор операторов, предназначенных для
манипуляции этими данными
3. набор классов для управления многопоточностью

Rx = Observables + LINQ + Schedulers
Зачем все это нужно?
                              GPS


              RSS   feeds




  Social
  media




                            Server management
Интерфейс IEnumerable

Pull-based последовательности представлены
интерфейсом IEnumerable. Это -
 коллекции в памяти (списки, вектора и
  т.д.)
 бесконечные последовательности
  (генераторы)
 xml-данные
 результаты запроса к БД
Интерфейс IEnumerable

public interface IEnumerable<out T>
{
    IEnumerator<T> GetEnumerator();
}                                     Ковариантность из
                                          .NET 4.0

public interface IEnumerator<out T> : IDisposable
{                            Блокирующая
    bool MoveNext();           операция
    T Current { get; }
    void Reset();
}
Упрощение интерфейса
IEnumerator

public interface IEnumerator<out T> : IDisposable
{
  (T | void | Exception) GetNext();
}




    T – следующий элемент
    void – окончание
    последовательности
    Exception – ошибка
Интерфейс IObservable

public interface IObservable<out T>
{
    IDisposable Subscribe(IObserver<T> observer);
}

public interface IObserver<in T>
{
    void OnNext(T value);
    void OnError(Exception error);
    void OnCompleted();
}
Pull vs Push
Pull vs Push
Простые последовательности

                             OnComplete

Observable.Empty<int>();                  new int[] {};

                              OnNext

Observable.Return(42);                    new int[] {42};

                              OnError
                                                  Итератор,
Observable.Throw<int>(ex);                      генерирующий
                                                 исключение
                                            Итератор, который не
Observable.Never<int>();                        возвращает
                                                управление
Методы Range

Observable.Range(0, 3);

 OnNext(0)    OnNext(1)   OnNext(2)




Enumerable.Range(0, 3);

  yield 0      yield 1     yield 2
Циклы for

var xs = Observable.Generate(   var xs = new IEnumerable<int> {
            0,                      for(int i = 0;
            x => x < 10,                i < 10;
            x => x + 1,                 i++)            Предположим,
            x => x);                  yield return i;    у нас есть
                                };                       синтаксис
                                                            анонимных
                                                            итераторов
xs.Subscribe(x => {             foreach(var x in xs) {
        Console.WriteLine(x);       Console.WriteLine(x);
                                }
   });
Контракт «реактивных»
последовательностей

 Grammar: OnNext* [OnCompleted | OnError]
 Методы наблюдателя вызываются
  последовательно
Упрощение работы с
интерфейсом IObserver
var xs = Observable.Range(0, 10);
1. Только OnNext:
xs.Subscribe(/*OnNext(int)*/x => Console.WriteLine(x));
2. OnNext и OnCompleted
xs.Subscribe(
    /*OnNext(int)*/x => Console.WriteLine(x),
    /*OnComplete*/() => Console.WriteLine("Completed"));
3. OnNext и OnError
xs.Subscribe(
    /*OnNext(int)*/x => Console.WriteLine(x),
    /*OnError(Exception)*/e => Console.WriteLine("Error: {0}", e));
4. OnNext, OnError и OnCompleted
xs.Subscribe(
    /*OnNext(int)*/x => Console.WriteLine(x),
    /*OnError(Exception)*/e => Console.WriteLine("Error: {0}", e),
    /*OnCompleted*/() => Console.WriteLine("Completed"));
Demo
События в .NET

 Объявление
    event Action<int> E;
 Публикация
    E(42);
 Подписка
    E += x => Console.WriteLine(x);
Rx

 Объявление
     ISubject<int> S = new Subject<int>();
 Публикация
     S.OnNext(42);
 Подписка
     S.Subscribe(x => Console.WriteLine(x));
Events vs Observables

class Program {                             class Program {

    event Action<int> E;                        ISubject<int> S = new Subject<int>();

    static void Main() {                        static void Main() {
      var p = new Program();                      var p = new Program();

        p.E += x => Console.WriteLine(x);           p.S.Subscribe(x => Console.WriteLine(x));

        p.E(1);                                     p.S.OnNext(1);
        p.E(2);                                     p.S.OnNext(2);
        p.E(3);                                     p.S.OnNext(3);
    }                                           }
}                                           }
Отписка от событий

 Events
static event Action<string> E;

//E += x => Console.WriteLine(x);
Action<string> action = x => Console.WriteLine(x);
E += action;
E -= action;

 Observables
static ISubject<int> S = new Subject<int>();

var token = S.Subscribe(x => Console.WriteLine(x));
token.Dispose();
«События» первого класса

Объект называют «объектом первого класса» когда он:
 может быть сохранен в переменной
 может быть передан в функцию как параметр
 может быть возвращен из функции как результат
 может быть создан во время выполнения программы
 внутренне самоидентифицируем (независим от
   именования)

http://ru.wikipedia.org/wiki/Объект_первого_класса
«События» первого класса

// Сохранение в переменной
IObservable<string> textChanged = …;

// Передача в качестве параметра
void ProcessRequests(IObservable<string> input) {…}

// Возвращение в качестве результата
IObservable<int> QueryServer() {…}
Возможности наблюдаемых
последовательностей
                                        Преобразование события в поток
                                                объектов Point
IObservable<Point> mouseMoves =
    from e in Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove")
    select e.EventArgs.Location;
                                            Фильтрация «событий»

var filtered = mouseMoves.Where(p => p.X == p.Y);

                                             Обработка «событий»
var subscription =
    filtered.Subscribe(p => Console.WriteLine("X, Y = {0}", p.X));

                                            Отписка от «событий»
subscription.Dispose();
Demo
Асинхронные операции
Classical Async Pattern
FileStream fs = File.OpenRead("data.txt");
                                               Невозможность использования
byte[] buffer = new byte[1024];               привычных языковых конструкций
                                                    (using, try/finally etc)



fs.BeginRead(buffer, 0, buffer.Length,    «Вывернутый» поток исполнения
                ar =>
                    {
                        int bytesRead = fs.EndRead(ar);
                        // Обработка данных в массиве buffer
                    },
                null);                    Сложность обработки ошибок, а
                                               также чтения и сопровождения
                                                           кода
FromAsyncPattern

static int LongRunningFunc(string s)
{
    Thread.Sleep(TimeSpan.FromSeconds(5));
                                                  FromAsyncPattern преобразует
    return s.Length;
                                                возвращаемое значение метода в
}                                                      IObservervable<T>

Func<string, int> longRunningFunc = LongRunningFunc;

Func<string, IObservable<int>> funcHelper =
    Observable.FromAsyncPattern<string, int>(
          longRunningFunc.BeginInvoke, longRunningFunc.EndInvoke);

IObservable<int> xs = funcHelper("Hello, String");
xs.Subscribe(x => Console.WriteLine("Length is " + x));
Tasks vs FromAsyncPattern

 Задачи (Tasks) – это унифицированный
  способ представления Single value
  asynchrony в .Net Framework
 Observables – Multi value asynchrony
 Существует простой способ
  преобразования Tasks -> Observables
Task -> ToObservable
                                          Метод расширения можно написать
                                          один раз, а использовать повсюду,
static class FuncExtensions
                                                   а не только с Rx
{
    internal static Task<int> ToTask(this Func<string, int> func, string s)
    {
        return Task<int>.Factory.FromAsync(
            func.BeginInvoke, func.EndInvoke, s, null);
    }
}
Func<string, int> longRunningFunc = LongRunningFunc;

                                          Это более предпочтительный способ,
string s = "Hello, String";                поскольку метод FromAsyncPattern
                                                скоро будет устаревшим
IObservable<int> xs = longRunningFunc.ToTask(s).ToObservable();

xs.Subscribe(x => Console.WriteLine("Length is " + x),
    () => Console.WriteLine("Task is finished"));
        }

   }
Чем Rx не является

 Rx не заменяет существующей «асинхронности»:
      .NET все еще незаменимы
      Асинхронные методы все так же применимы в библиотеках
      Задачи представляют собой single value asynchrony
      Существуют и другие асинхронные источники, как SSIS,
       PowerShell, etc
 Но rx…
    Унифицирует работу
    Предоставляет возможность композиции
    Предоставляет обобщенные операторы
 Так что rx – это …
    Мост!
Demo
Управление многопоточность

 Управление многопоточностью
  осуществляется с помощью
  интерфейса IScheduler
var xs = Observable.Range(0, 10, Scheduler.ThreadPool);

xs.Subscribe(x => Console.WriteLine(x));

                                     Параметризация с помощью
  Будет исполняться в контексте
                                  IScheduler доступна в большинстве
          планировщика
                                               операций
Синхронизация

   Обновление пользовательского интерфейса
Label lbl = new Label();
Form frm = new Form() {Controls = {lbl}};

var xs = Observable.Return(42, Scheduler.ThreadPool);

xs.Subscribe(x =>
{
    Thread.Sleep(1000);
    lbl.Text = "Result is " + x;
});




 Использование ObserveOn
xs.ObserveOn(frm).Subscribe(x =>
{
    Thread.Sleep(1000);                      IScheduler поддерживает разные
    lbl.Text = "Result is " + x;                контексты синхронизации
});
Demo
Что мы изучили?

   Введение в реактивные расширения
   Дуализм интерфейсов
   Основы Rx
   Observable sequences
   Events и Observables
   Observables и асинхронные операции
   Concurrency

                                         1-40
Experimental vs Stable

 Две версии библиотеки Reactive
  Extensions:
   Stable
   Experimental
 Interactive Extensions
Где взять?

 NuGet
 Web - http://msdn.microsoft.com/en-
  us/data/gg577610
 Can’t find? Use google
Дополнительные ссылки

   The Reactive Extensions (Rx)... (Data Developer Center) -
    http://msdn.microsoft.com/en-us/data/gg577609
   Reactive Extensions (MSDN) - http://msdn.microsoft.com/en-
    us/library/hh242985(v=vs.103).aspx
   Rx Team Blog - http://blogs.msdn.com/b/rxteam/
   Реактивные расширения и асинхронные операции -
    http://sergeyteplyakov.blogspot.com/2010/11/blog-post.html
Roslyn CTP is awailable!




http://msdn.microsoft.com/ru-ru/roslyn
Вопросы?

Mais conteúdo relacionado

Mais procurados

Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Dima Dzuba
 
Java. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторыJava. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторыUnguryan Vitaliy
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Alexey Paznikov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Dima Dzuba
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Dima Dzuba
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
 
20090222 parallel programming_lecture01-07
20090222 parallel programming_lecture01-0720090222 parallel programming_lecture01-07
20090222 parallel programming_lecture01-07Computer Science Club
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Yandex
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...Alexey Paznikov
 
Лекция 6
Лекция 6Лекция 6
Лекция 6itc73
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Dima Dzuba
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...OdessaFrontend
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java scriptViktor Andreev
 

Mais procurados (20)

Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6
 
Java. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторыJava. Переменные, типы данных, операторы
Java. Переменные, типы данных, операторы
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
 
20090222 parallel programming_lecture01-07
20090222 parallel programming_lecture01-0720090222 parallel programming_lecture01-07
20090222 parallel programming_lecture01-07
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
 
Лекция 6
Лекция 6Лекция 6
Лекция 6
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 
Stream API
Stream APIStream API
Stream API
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
 
функции в Java script
функции в Java scriptфункции в Java script
функции в Java script
 

Semelhante a Reactive extensions

Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с RxGoSharp
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAlex Tumanoff
 
Reactive Extensions
Reactive ExtensionsReactive Extensions
Reactive ExtensionsGetDev.NET
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Sigma Software
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Vasya Petrov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3etyumentcev
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...solit
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.Igor Shkulipa
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутAndrey Karpov
 

Semelhante a Reactive extensions (20)

Живые приложения с Rx
Живые приложения с RxЖивые приложения с Rx
Живые приложения с Rx
 
C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
C# Deep Dive
C# Deep DiveC# Deep Dive
C# Deep Dive
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
 
Reactive Extensions
Reactive ExtensionsReactive Extensions
Reactive Extensions
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
 
Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1Подробная презентация JavaScript 6 в 1
Подробная презентация JavaScript 6 в 1
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Rx
RxRx
Rx
 
Zagursky
ZagurskyZagursky
Zagursky
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минут
 
Async
AsyncAsync
Async
 
Luxoft async.net
Luxoft async.netLuxoft async.net
Luxoft async.net
 
Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.
 

Reactive extensions

  • 2. О Вашем инструкторе  Сергей Тепляков  Visual C# MVP, RSDN Team member  Sergey.Teplyakov@gmail.com  SergeyTeplyakov.blogspot.com 1-2
  • 3. Необходимая подготовка Слушатели должны:  Быть знакомы с основами языка C# и платформы .Net  Обладать базовыми знаниями многопоточности  Быть знакомы с LINQ (Language Integrated Query) 1-4
  • 4. Roadmap  Введение в реактивные расширения  Дуализм интерфейсов  Основы Rx  Observable sequences  Events и Observables  Observables и асинхронные операции  Concurrency  Новости из Редмонта 1-5
  • 6. Реактивное программирование Парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что выполняемая модель должна автоматически распространять изменения сквозь поток данных. http://ru.wikipedia.org/ /wiki/Реактивное_программирование
  • 7. Реактивная модель "Принцип Голливуда" – "Не звоните нам, мы сами вам позвоним" (Hollywood Principle - Don't call us, we'll call you)
  • 8. Rx - это 1. набор классов, представляющих собой асинхронный поток данных 2. набор операторов, предназначенных для манипуляции этими данными 3. набор классов для управления многопоточностью Rx = Observables + LINQ + Schedulers
  • 9. Зачем все это нужно? GPS RSS feeds Social media Server management
  • 10. Интерфейс IEnumerable Pull-based последовательности представлены интерфейсом IEnumerable. Это -  коллекции в памяти (списки, вектора и т.д.)  бесконечные последовательности (генераторы)  xml-данные  результаты запроса к БД
  • 11. Интерфейс IEnumerable public interface IEnumerable<out T> { IEnumerator<T> GetEnumerator(); } Ковариантность из .NET 4.0 public interface IEnumerator<out T> : IDisposable { Блокирующая bool MoveNext(); операция T Current { get; } void Reset(); }
  • 12. Упрощение интерфейса IEnumerator public interface IEnumerator<out T> : IDisposable { (T | void | Exception) GetNext(); } T – следующий элемент void – окончание последовательности Exception – ошибка
  • 13. Интерфейс IObservable public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } public interface IObserver<in T> { void OnNext(T value); void OnError(Exception error); void OnCompleted(); }
  • 16. Простые последовательности OnComplete Observable.Empty<int>(); new int[] {}; OnNext Observable.Return(42); new int[] {42}; OnError Итератор, Observable.Throw<int>(ex); генерирующий исключение Итератор, который не Observable.Never<int>(); возвращает управление
  • 17. Методы Range Observable.Range(0, 3); OnNext(0) OnNext(1) OnNext(2) Enumerable.Range(0, 3); yield 0 yield 1 yield 2
  • 18. Циклы for var xs = Observable.Generate( var xs = new IEnumerable<int> { 0, for(int i = 0; x => x < 10, i < 10; x => x + 1, i++) Предположим, x => x); yield return i; у нас есть }; синтаксис анонимных итераторов xs.Subscribe(x => { foreach(var x in xs) { Console.WriteLine(x); Console.WriteLine(x); } });
  • 19. Контракт «реактивных» последовательностей  Grammar: OnNext* [OnCompleted | OnError]  Методы наблюдателя вызываются последовательно
  • 20. Упрощение работы с интерфейсом IObserver var xs = Observable.Range(0, 10); 1. Только OnNext: xs.Subscribe(/*OnNext(int)*/x => Console.WriteLine(x)); 2. OnNext и OnCompleted xs.Subscribe( /*OnNext(int)*/x => Console.WriteLine(x), /*OnComplete*/() => Console.WriteLine("Completed")); 3. OnNext и OnError xs.Subscribe( /*OnNext(int)*/x => Console.WriteLine(x), /*OnError(Exception)*/e => Console.WriteLine("Error: {0}", e)); 4. OnNext, OnError и OnCompleted xs.Subscribe( /*OnNext(int)*/x => Console.WriteLine(x), /*OnError(Exception)*/e => Console.WriteLine("Error: {0}", e), /*OnCompleted*/() => Console.WriteLine("Completed"));
  • 21. Demo
  • 22. События в .NET  Объявление event Action<int> E;  Публикация E(42);  Подписка E += x => Console.WriteLine(x);
  • 23. Rx  Объявление ISubject<int> S = new Subject<int>();  Публикация S.OnNext(42);  Подписка S.Subscribe(x => Console.WriteLine(x));
  • 24. Events vs Observables class Program { class Program { event Action<int> E; ISubject<int> S = new Subject<int>(); static void Main() { static void Main() { var p = new Program(); var p = new Program(); p.E += x => Console.WriteLine(x); p.S.Subscribe(x => Console.WriteLine(x)); p.E(1); p.S.OnNext(1); p.E(2); p.S.OnNext(2); p.E(3); p.S.OnNext(3); } } } }
  • 25. Отписка от событий  Events static event Action<string> E; //E += x => Console.WriteLine(x); Action<string> action = x => Console.WriteLine(x); E += action; E -= action;  Observables static ISubject<int> S = new Subject<int>(); var token = S.Subscribe(x => Console.WriteLine(x)); token.Dispose();
  • 26. «События» первого класса Объект называют «объектом первого класса» когда он:  может быть сохранен в переменной  может быть передан в функцию как параметр  может быть возвращен из функции как результат  может быть создан во время выполнения программы  внутренне самоидентифицируем (независим от именования) http://ru.wikipedia.org/wiki/Объект_первого_класса
  • 27. «События» первого класса // Сохранение в переменной IObservable<string> textChanged = …; // Передача в качестве параметра void ProcessRequests(IObservable<string> input) {…} // Возвращение в качестве результата IObservable<int> QueryServer() {…}
  • 28. Возможности наблюдаемых последовательностей Преобразование события в поток объектов Point IObservable<Point> mouseMoves = from e in Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove") select e.EventArgs.Location; Фильтрация «событий» var filtered = mouseMoves.Where(p => p.X == p.Y); Обработка «событий» var subscription = filtered.Subscribe(p => Console.WriteLine("X, Y = {0}", p.X)); Отписка от «событий» subscription.Dispose();
  • 29. Demo
  • 30. Асинхронные операции Classical Async Pattern FileStream fs = File.OpenRead("data.txt"); Невозможность использования byte[] buffer = new byte[1024]; привычных языковых конструкций (using, try/finally etc) fs.BeginRead(buffer, 0, buffer.Length, «Вывернутый» поток исполнения ar => { int bytesRead = fs.EndRead(ar); // Обработка данных в массиве buffer }, null); Сложность обработки ошибок, а также чтения и сопровождения кода
  • 31. FromAsyncPattern static int LongRunningFunc(string s) { Thread.Sleep(TimeSpan.FromSeconds(5)); FromAsyncPattern преобразует return s.Length; возвращаемое значение метода в } IObservervable<T> Func<string, int> longRunningFunc = LongRunningFunc; Func<string, IObservable<int>> funcHelper = Observable.FromAsyncPattern<string, int>( longRunningFunc.BeginInvoke, longRunningFunc.EndInvoke); IObservable<int> xs = funcHelper("Hello, String"); xs.Subscribe(x => Console.WriteLine("Length is " + x));
  • 32. Tasks vs FromAsyncPattern  Задачи (Tasks) – это унифицированный способ представления Single value asynchrony в .Net Framework  Observables – Multi value asynchrony  Существует простой способ преобразования Tasks -> Observables
  • 33. Task -> ToObservable Метод расширения можно написать один раз, а использовать повсюду, static class FuncExtensions а не только с Rx { internal static Task<int> ToTask(this Func<string, int> func, string s) { return Task<int>.Factory.FromAsync( func.BeginInvoke, func.EndInvoke, s, null); } } Func<string, int> longRunningFunc = LongRunningFunc; Это более предпочтительный способ, string s = "Hello, String"; поскольку метод FromAsyncPattern скоро будет устаревшим IObservable<int> xs = longRunningFunc.ToTask(s).ToObservable(); xs.Subscribe(x => Console.WriteLine("Length is " + x), () => Console.WriteLine("Task is finished")); } }
  • 34. Чем Rx не является  Rx не заменяет существующей «асинхронности»:  .NET все еще незаменимы  Асинхронные методы все так же применимы в библиотеках  Задачи представляют собой single value asynchrony  Существуют и другие асинхронные источники, как SSIS, PowerShell, etc  Но rx…  Унифицирует работу  Предоставляет возможность композиции  Предоставляет обобщенные операторы  Так что rx – это …  Мост!
  • 35. Demo
  • 36. Управление многопоточность  Управление многопоточностью осуществляется с помощью интерфейса IScheduler var xs = Observable.Range(0, 10, Scheduler.ThreadPool); xs.Subscribe(x => Console.WriteLine(x)); Параметризация с помощью Будет исполняться в контексте IScheduler доступна в большинстве планировщика операций
  • 37. Синхронизация  Обновление пользовательского интерфейса Label lbl = new Label(); Form frm = new Form() {Controls = {lbl}}; var xs = Observable.Return(42, Scheduler.ThreadPool); xs.Subscribe(x => { Thread.Sleep(1000); lbl.Text = "Result is " + x; });  Использование ObserveOn xs.ObserveOn(frm).Subscribe(x => { Thread.Sleep(1000); IScheduler поддерживает разные lbl.Text = "Result is " + x; контексты синхронизации });
  • 38. Demo
  • 39. Что мы изучили?  Введение в реактивные расширения  Дуализм интерфейсов  Основы Rx  Observable sequences  Events и Observables  Observables и асинхронные операции  Concurrency 1-40
  • 40. Experimental vs Stable  Две версии библиотеки Reactive Extensions:  Stable  Experimental  Interactive Extensions
  • 41. Где взять?  NuGet  Web - http://msdn.microsoft.com/en- us/data/gg577610  Can’t find? Use google
  • 42. Дополнительные ссылки  The Reactive Extensions (Rx)... (Data Developer Center) - http://msdn.microsoft.com/en-us/data/gg577609  Reactive Extensions (MSDN) - http://msdn.microsoft.com/en- us/library/hh242985(v=vs.103).aspx  Rx Team Blog - http://blogs.msdn.com/b/rxteam/  Реактивные расширения и асинхронные операции - http://sergeyteplyakov.blogspot.com/2010/11/blog-post.html
  • 43. Roslyn CTP is awailable! http://msdn.microsoft.com/ru-ru/roslyn

Notas do Editor

  1. Обращаю внимание, что под «управлением» подразумевается не синхронизация, а «параметризация» определенных методов дополнительными объектами, которые знают, в каком контексте необходимо выполнить определенную операцию. Наиболее типичным примерам такого управления является использование специализированных планировщиков, которые будут вызывать методы наблюдателя в контексте синхронизации.
  2. Rx - это клей, &quot;склеивающий&quot; разнородныеасинхронныеисточникиданных.
  3. Эта пара интерфейс как раз и представляют ту самую pull-последовательность, о которойшларечьраньше. Перебором элементовпоследовательностизанимаетсявызывающий код. Пользовательдолженвызвать метод MoveNext для перехода к следующемуэлементу, и толькоесли (и когда) он вернулtrue (может пройти полдня, кстати), то нужнообратиться к свойствуCurrent для полученияпоследующегоэлементапоследовательности.Условныеобозначения для рисования: IE - IEnumerable и IR - IEnumeratorСпецификторout в объявлении интерфейсов появился только в .NET 4.0 и означает, что этот интерфейс ковариантный. В данном случае это означает, что из этого интерфейса мы можем «вытягивать» данные, а не помещать их туда. И эта однонаправленность интерфейса позволяет его использовать в коде «полиморфным образом». Например, если у нас есть класс Base и его наследник – класс Derived, то в нашем коде мы можем использовать следующее:Derived d = new Derived();Base b = d;Это означает, что переменную с типом наследника мы можем трактовать, как переменную базового класса, но это совсем не значит, что мы можем трактовать последовательность объектов типа Derived, как последовательность типов Base. Точнее, мы не могли этого делать до появления ковариатности и контравариантностиинтрфейсов.Теперь, если обобщенный параметр объявлен со спецификатором out, то этот параметр становится ковариантным. И все, что применялось к простым переменным (нашим переменным b и d), теперь может применяться к интерфесом: IEnumerable&lt;Derived&gt; и IEnumerable&lt;Base&gt;:IEnumerable&lt;Derived&gt; d = new List&lt;Derived&gt;(); IEnumerable&lt;Base&gt; b = d;
  4. Барточеньприкольновыразился, когдасказал, чтозачастуюпаттерны в бандечетырехсгруппированывместе по схожести. Новотсхожестьмеждуитератором и наблюдателемникак не обозначена. В целом, этосвязано с тем, что push-basedколлекцииявляютсялишьчастнымслучаемнаблюдателя, и этотпаттернможетприменяться и в других контекстах. Но, тем не менее, еслипосмотретьподэтимуглом, то симетриямеждуэтимидвумяпаттернамиприсутствует.
  5. Первые три слайда показывают семантическую схожесть (или проводят аналогии) между некоторыми встроенными и простыми наблюдаемыми последовательностями и обычными структурами данных и последовательностями.
  6. Но прежде чем переходить к небольшой демонстрации, давайте рассмотрим еще несколько важных тем.Во-первых, нам нужно рассмотреть упрощенную версию метода Subscribe, который вместо того, чтобы принимать интерфейс IObserver принимает лямбда-выражение. Кроме того, нам нужно рассмотреть процесс отписки от событий, чтобы рассматриваемые пример были более понятными.
  7. Аналогично тому, как вы не можете получить следующий элемент последовательности, пока вы не получили предыдущий, асинхронные последовательности также предоставляют подобные гарантии. (Да, кстати, вы можете добиться этого, но для этого придется попотеть). Точно также, правильная реактивная библиотека, которая следует определенным рекомендациям (существует специальный документ, который называется Rx Design Guidelines) не должна отправлять одному и тому же наблюдателю следующие элемент, пока не завершилась обработка предыдущего элемента.
  8. Тут словам можно сказать, что поскольку у нас нет, как в Джаве анонимной реализации интерфейсов, то мы можем это эмулировать с помощью методов расширения
  9. Запустить голый проект в Visual Studio 2010 с добавленными ссылками на Rx и показать несколько простых и примитивных примеров. В частности, показать, что при добавлении соответствующей using директивы мы получим множество методов расширения, которые позволят нам использовать LINQ во всей красе.Затем, дать пример, который генерирует последовательность данных и немного с ней поиграться.Добавить простой метод Generateс параметром TimeSpan, показать, что основной поток все еще не заблокирован.Потом запустить Generate с random-ом и поиграться еще. Добавить DistinctUntilChanged();, а потом Buffer с печатью всех элементов, а потом с суммой.
  10. Здесь нужно обязательно сказать и, возможно даже показать сложность с отпиской от события. Ведь для нормальной отписки от события
  11. Еще одним недостатком событий, о котором следует упомянуть – это отсутствие композиции. Мы не можем отфильтровать данные одного события и сделать из него другое. Для этого нужно добавить совершенно новое событие. А если нам нужно несколько способов манипулирования (фильтрации, получения проекции), то сложность решения резко возрастает.
  12. Запустить VS2010 и попробовать отфильтровать события пользовательского интерфейса и показать, что из этого получается.
  13. Фраза о том, что Task – это single value asynchrony etc
  14. Очень важно сказать, что RX строятсяon top of existing abstractions but they’re not going to replace them. Остается множество мест, где события нужно использовать напрямую, не оборачивая их ни в какие последовательности. Мы кликнули на форме и получили событие загрузки формы, мы никогда не получим множество событий загрузки формы, которые мы хотели бы композировать каким-то хитрым образом. Если нам нужно обработать событие клика мышки, то опять же, нет никакого смысла добавлять что-либо.Точно так же, все существующие примитивы в .NET Framework остаются такими же ценными, какими они были вчера. Никто не собирается изменять низкоуровневый код, который прекрасно работает и заточен лишь для одной цели. Но теперь, работая с ним его легко можно обернуть в более высокоуровневые примитивы и работать с ним с более высокого уровня абстракции.
  15. Примеры, посвященные асинхронности.
  16. Описать и рассказать об интерфейсе IScheduler, который инкапсулирует в себе вопросы асинхронности и управления ею.По умолчанию используется скеджулер, который называется Immediate, т.е. который не делает никакой многопоточности. И это разумно, поскольку многопоточность не бесплатна. Но практически все операции, типа Return, Range и т.д. принимают дополнительный параметр (т.е. содержат соответствующую перегрузку), который принимает интерфейс Ischeduler.В большинстве случаев об этом параметре можно не думать, поскольку решение по умолчанию нам подходит. Так, например, метод Generate, который принимает еще и TimeSpan по умолчанию использует ThreadPool, поскольку использование текущего потока сделает этот метод бесполезным.
  17. А вот здесь показать, как упадет тот же самый пример без асинхронности, но будет жить, когда мы ее добавим контекст синхронизации!
  18. Пример из выступления Вейеса!