Re[4]: RX - живой ли ?
От: Nikolay_P_I  
Дата: 23.07.13 09:07
Оценка:
Здравствуйте, Ikemefula, Вы писали:

N_P>>Потребность, собственно, как раз в обработке потока пакетов данных, частным случаем которого являются очереди сообщений. Без написания велосипедов. Потому что правильный велосипед для решения этой задачи должен уметь как минимум фильтрацию, агрегацию, ограниченную буферизацию и обработку ошибок. Быть неблокирующим, многопоточным и не жрать ресурсы в бездействии. Очень непростой велосипед.


I>Практически все это короутины умеют искаропки.


Но, как я понимаю — на .NET их нет ? Готовых, стабильных и понятных ?
Re[5]: RX - живой ли ?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 23.07.13 09:12
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

I>>Практически все это короутины умеют искаропки.


N_P>Но, как я понимаю — на .NET их нет ? Готовых, стабильных и понятных ?


Я ж вроде сразу это сказал
Re[12]: RX - живой ли ?
От: ionoy Эстония www.ammyui.com
Дата: 23.07.13 09:14
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, ionoy, Вы писали:


I>>Здравствуйте, Ikemefula, Вы писали:


I>>>что такое получение параметров ?

I>>Видимо с этого и стоило начинать. Есть некий поток пакетов — PacketStream, тип которого IObservable<IPacket>.
I>Это не интересно, у меня нет никаких обсервабл. Кто является источником пакетов ?

Ок, опишу в общих чертах алгоритм (NB! это описание кода, а не реальный код из проекта):

Читаем байты из последовательного порта и скармливаем их парсеру
var port = new SerialPort();
while(isProcessing) {
   if (port.BytesToRead > 0) {
       var buf = new byte[port.BytesToRead];
       port.Read(buf, 0, buf.Length);
       parser.Append(buf);
   }
}


Парсер добавляет их в очередь
void Append(byte[] buf) {
  _queue.Enqueue(buf);
}


В отдельном потоке происходит парсинг на основе машины состояний.
Как только новый пакет готов, он отсылается всем подписчикам:

if (_readyForDispatching.TryDequeue(out packet))
   _stream.OnNext(packet);


Подписчики работают с этим потоком через свойство PacketStream.
Так как PacketStream — это IObservable<Packet>, то мы можем пользоваться всей обширной библиотекой операторов RX. Появляется возможность пакеты комбинировать, фильтровать, анализировать последовательности, обнаруживать запаздывания и так далее.
Код работы с PacketStream я уже приводил, так что думаю не стоит повторяться.

I>Ну извини, у меня нет IObservable => задача не решаема.

Ну, ты ведь представляешь себе в общих чертах, что из какого-то потока приходят пакеты, дальше надо с ними работать. Пофиг Observable это, или что-то другое. Какую работу выполняет мой код я уже описал в начале ветки, так что давай уже, приводи свой вариант на корутинах/async-await.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[4]: RX - живой ли ?
От: ionoy Эстония www.ammyui.com
Дата: 23.07.13 09:29
Оценка:
Здравствуйте, Ikemefula, Вы писали:


N_P>>Пока я знаю 2 более-менее подходящих готовых варианта решения — TPL Workflow и RX. Вот и спрашиваю — кто из них как поживает

I>"я уже два с половиной раза прочёл Introduction to RX, но всё равно частенько встречаюсь с вещами, которые мне непонятны. То есть порог вхождения у него достаточно высокий."
I>И это пишет человек который во всю злоупотребляет Немерле на каждом шагу

Это совсем не обязательно означает, что RX плох. Просто сама концепция для меня была достаточно нова, а так как там есть операторы, которые выполняют сложную логику, то конечно сходу так и не въедешь во всё.

Опять же, я не говорю, что RX идеален. Там, много недостатков, которые являются следствием ограниченности C#. Но если наберёшься достаточно опыта, то сложно найти инструмент более мощный и универсальный.
Всё как с Немерле
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.07.13 18:39
Оценка: 9 (1)
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Помнится столько анонсов было, а вопросов тут по нему — не вижу.


N_P>Взлетела технология-то или оказалась никому кроме гиков не нужной ?


N_P>Стоит на него массово перходить или TPL WorkFlow лучше заняться ?


Проблема Rx в том, что это а) очень сложно б)очень конкурирует с TPL.

TPL очень сильно развивается — async\await в компиляторе, нормальная библиотека примитивов, поддержка в Win8(WinRT), WindowsForms, WebForms, MVC и WebAPI, под TPL допиливается ядро .NET FW

Во многих случаях быстрее и выгоднее написать на TPL, чем на Rx.

С развитием TPL область применения Rx сужается. Причем уже сузилась до такой степени, что стала не нужна большинству программистов, вот и результат.

Чуть больше года назад писал пост-сравнение http://gandjustas.blogspot.ru/2012/04/task-parallel-library.html
Большая часть описанных проблем уже решена в готовых библиотеках. Да и такого уровня задачи встречаются нечасто (на моей памяти такого вообще не было).
Re[2]: RX - живой ли ?
От: Nikolay_P_I  
Дата: 24.07.13 04:26
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Чуть больше года назад писал пост-сравнение http://gandjustas.blogspot.ru/2012/04/task-parallel-library.html


А на TPL Workflow задачу решать не пробовали ? Именно WorkFlow, там, вроде, есть функционал продолжения и оно вообще на RX местами похоже.

G>Большая часть описанных проблем уже решена в готовых библиотеках. Да и такого уровня задачи встречаются нечасто (на моей памяти такого вообще не было).


А какие библиотеки есть ? Что посмотреть ?

А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений.
Re[3]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.07.13 06:37
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, gandjustas, Вы писали:


G>>Чуть больше года назад писал пост-сравнение http://gandjustas.blogspot.ru/2012/04/task-parallel-library.html


N_P>А на TPL Workflow задачу решать не пробовали ? Именно WorkFlow, там, вроде, есть функционал продолжения и оно вообще на RX местами похоже.


Он там излишне. На текущем уровне развития и обычный tpl решает. Tpl Dataflow делает тоже, что и Rx на высоком уровне.

G>>Большая часть описанных проблем уже решена в готовых библиотеках. Да и такого уровня задачи встречаются нечасто (на моей памяти такого вообще не было).


N_P>А какие библиотеки есть ? Что посмотреть ?

В nuget их полно. Можно отсюда начать — http://blogs.msdn.com/b/pfxteam/archive/2013/04/03/tasks-monads-and-linq.aspx


N_P>А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений.

Это как раз кейс для Rx. Увы такие вещи мало кто пишет. Все работают уровнем выше, например webapi используют. Он внутри весь на тасках.
Re[4]: RX - живой ли ?
От: Nikolay_P_I  
Дата: 24.07.13 07:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Чуть больше года назад писал пост-сравнение http://gandjustas.blogspot.ru/2012/04/task-parallel-library.html


N_P>>А на TPL Workflow задачу решать не пробовали ? Именно WorkFlow, там, вроде, есть функционал продолжения и оно вообще на RX местами похоже.

G>Он там излишне. На текущем уровне развития и обычный tpl решает. Tpl Dataflow делает тоже, что и Rx на высоком уровне.

Это именно в плане сравнения. У вас на TPL получился жуткий код. Интересно — как оно бы выглядело на TPL WorkFlow.
Re[4]: RX - живой ли ?
От: Nikolay_P_I  
Дата: 24.07.13 07:28
Оценка:
Здравствуйте, gandjustas, Вы писали:

N_P>>А какие библиотеки есть ? Что посмотреть ?

G>В nuget их полно. Можно отсюда начать — http://blogs.msdn.com/b/pfxteam/archive/2013/04/03/tasks-monads-and-linq.aspx

Это все не то. Вопрос не в монадах. Вопрос в обвязке. Буфера, отмена, агрегаты исключений. А если самом у все это писать — проще сразу на TPL. Знакомее.

N_P>>А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений.

G>Это как раз кейс для Rx. Увы такие вещи мало кто пишет. Все работают уровнем выше, например webapi используют. Он внутри весь на тасках.

А если данные от датчиков ? А если это документооборот ? Не Webом же единым.
Re[5]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.07.13 09:14
Оценка: 18 (2)
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, gandjustas, Вы писали:


G>>>>Чуть больше года назад писал пост-сравнение http://gandjustas.blogspot.ru/2012/04/task-parallel-library.html


N_P>>>А на TPL Workflow задачу решать не пробовали ? Именно WorkFlow, там, вроде, есть функционал продолжения и оно вообще на RX местами похоже.

G>>Он там излишне. На текущем уровне развития и обычный tpl решает. Tpl Dataflow делает тоже, что и Rx на высоком уровне.

N_P>Это именно в плане сравнения. У вас на TPL получился жуткий код. Интересно — как оно бы выглядело на TPL WorkFlow.


На самом деле сейчас можно написать так:

static Task<int> HeightTask<T>(T element, Func<T, IEnumerable<T>> childSelector)
{
    return Task.Factory.StartNew(() =>
        Task.WhenAll(childSelector(element).Select(c => HeightTask(c, childSelector)))
            .ContinueWith(r => r.Result.Aggregate(0, Math.Max) + 1)
        ).Unwrap();
}

И это работает в 15 раз быстрее Rx. Без всяких дополнительных библиотек.
Re[5]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.07.13 09:28
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, gandjustas, Вы писали:


N_P>>>А какие библиотеки есть ? Что посмотреть ?

G>>В nuget их полно. Можно отсюда начать — http://blogs.msdn.com/b/pfxteam/archive/2013/04/03/tasks-monads-and-linq.aspx

N_P>Это все не то. Вопрос не в монадах. Вопрос в обвязке. Буфера, отмена, агрегаты исключений. А если самом у все это писать — проще сразу на TPL. Знакомее.

Обвязка очень легко делается когда есть удобные средства композиции.


N_P>>>А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений.

G>>Это как раз кейс для Rx. Увы такие вещи мало кто пишет. Все работают уровнем выше, например webapi используют. Он внутри весь на тасках.

N_P>А если данные от датчиков ?

Rx, его модель идеально подходит для датчиков.

N_P>А если это документооборот ? Не Webом же единым.

А зачем в документообороте вообще такое?
Re[13]: RX - живой ли ?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.07.13 08:13
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Ок, опишу в общих чертах алгоритм (NB! это описание кода, а не реальный код из проекта):


Я не сильно понимаю как у тебя работает Retry, можешь показать что там такое?
Re[2]: RX - живой ли ?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.07.13 10:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Во многих случаях быстрее и выгоднее написать на TPL, чем на Rx.


Какое то очень странное противопоставление. Rx никоим образом не претендует на замену TPL, более того, асинхронная часть в нем как раз поверх TPL и построена.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[14]: RX - живой ли ?
От: ionoy Эстония www.ammyui.com
Дата: 26.07.13 11:55
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Я не сильно понимаю как у тебя работает Retry, можешь показать что там такое?

Retry — это оператор RX. Вот тут наглядно описан механизм работы: http://www.introtorx.com/content/v1.0.10621.0/11_AdvancedErrorHandling.html#Retry
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[3]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.07.13 13:05
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, gandjustas, Вы писали:


G>>Во многих случаях быстрее и выгоднее написать на TPL, чем на Rx.


AVK>Какое то очень странное противопоставление. Rx никоим образом не претендует на замену TPL, более того, асинхронная часть в нем как раз поверх TPL и построена.


В RX concurrency построена поверх свой абстракции IScheduler. Реализация IScheduler может быть и на тасках, но паттерн использования тасков в этом случае отличается от того, под что затачивается TPL. Поэтому при примерно одинаковом коде Rx таки медленнее, хотя в реальных случаях с реальным IO это разница будет незаметна.

Я не писал что Rx претендует на замену TPL. Скорее наоборот. Rx исторически раньше появился в "широком доступе". Но после появления async\await потребность в нем резко упала.
Re[4]: RX - живой ли ?
От: ionoy Эстония www.ammyui.com
Дата: 26.07.13 13:26
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Я не писал что Rx претендует на замену TPL. Скорее наоборот. Rx исторически раньше появился в "широком доступе". Но после появления async\await потребность в нем резко упала.

Честно говоря, для меня async/await вообще не пересекается с RX. Если await — это грубо говоря сахар для ContinueWith, то RX — это средство управления потоками событий/данных и т.д. Я не вижу в TPL инструментов для работы с последовательностями.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[5]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.07.13 13:44
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:


G>>Я не писал что Rx претендует на замену TPL. Скорее наоборот. Rx исторически раньше появился в "широком доступе". Но после появления async\await потребность в нем резко упала.

I>Честно говоря, для меня async/await вообще не пересекается с RX. Если await — это грубо говоря сахар для ContinueWith, то RX — это средство управления потоками событий/данных и т.д. Я не вижу в TPL инструментов для работы с последовательностями.

1) await не просто сахар для ContinueWith, а полноценное средство композиции для тасков. Попробуй без await написать вызов дочерней задачи в цикле. Код аццкий выйдет.
2) Rx изначально пользовался Linq, который является идеальным средством композиции. Поэтому до .NET 4.5 было в разы выгоднее делать на Rx, чем на TPL. Тем более что потоки событий можно свести к асинхронным таскам (наоборот нельзя).
3) Когда появился async\await и нормальные примитивы выяснилось что большая часть задач покрывается тасками. Для Rx остается маленький кусочек задач, где есть потоки данных и затраты на использование Rx окупаются (в основном затраты на то чтобы разобраться как оно работает).
Re[6]: RX - живой ли ?
От: ionoy Эстония www.ammyui.com
Дата: 26.07.13 14:01
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>1) await не просто сахар для ContinueWith, а полноценное средство композиции для тасков. Попробуй без await написать вызов дочерней задачи в цикле. Код аццкий выйдет.

Скажем так, это качественный сахар

G>2) Rx изначально пользовался Linq, который является идеальным средством композиции. Поэтому до .NET 4.5 было в разы выгоднее делать на Rx, чем на TPL. Тем более что потоки событий можно свести к асинхронным таскам (наоборот нельзя).

Мне всё-таки кажется, что это разные инструменты, которые используются в одном домене. Вроде дрели и шуруповёрта — при желании их можно взаимозаменять, но есть задачи где использование неверного инструмента принесёт много головной боли.
Вот смотри http://rxwiki.wikidot.com/observable-operators.
Большинство операторов нацелены на управление потоками, т.е. ты можешь написать:

stream.OpA()
      .OpB()
      .OpC()


и получить асинхронную последовательность, которая ведёт себя так, как ты хочешь. Конечно, теоретически это можно будет перенести на TPL, но выглядеть оно будет не так красиво.

G>3) Когда появился async\await и нормальные примитивы выяснилось что большая часть задач покрывается тасками. Для Rx остается маленький кусочек задач, где есть потоки данных и затраты на использование Rx окупаются (в основном затраты на то чтобы разобраться как оно работает).

Мне кажется, что кусочек задач не такой уж и маленький. Так как такого инструмента раньше не существовало, то мы ещё не нашли все проблемы, которые элегантно решаются на RX. Одна из неожиданных областей применения это UI (и я даже не говорю про ReactiveUI).
В отличие от async/await, и TPL в целом, которые сближают наш опыт работы в одном потоке и программирование в асинхронном мире.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[7]: RX - живой ли ?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.07.13 14:19
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:


G>>2) Rx изначально пользовался Linq, который является идеальным средством композиции. Поэтому до .NET 4.5 было в разы выгоднее делать на Rx, чем на TPL. Тем более что потоки событий можно свести к асинхронным таскам (наоборот нельзя).

I>Мне всё-таки кажется, что это разные инструменты, которые используются в одном домене. Вроде дрели и шуруповёрта — при желании их можно взаимозаменять, но есть задачи где использование неверного инструмента принесёт много головной боли.
I>Вот смотри http://rxwiki.wikidot.com/observable-operators.
Я прекрасно знаю Rx есличто.

I>Большинство операторов нацелены на управление потоками, т.е. ты можешь написать:


I>
I>stream.OpA()
I>      .OpB()
I>      .OpC()
I>


Тоже самое можно и с тасками написать.
Вопрос не в синтаксисе. А в том что ты потом с результатом можно делать.


G>>3) Когда появился async\await и нормальные примитивы выяснилось что большая часть задач покрывается тасками. Для Rx остается маленький кусочек задач, где есть потоки данных и затраты на использование Rx окупаются (в основном затраты на то чтобы разобраться как оно работает).

I>Мне кажется, что кусочек задач не такой уж и маленький. Так как такого инструмента раньше не существовало, то мы ещё не нашли все проблемы, которые элегантно решаются на RX. Одна из неожиданных областей применения это UI (и я даже не говорю про ReactiveUI).
Это только кажется. ReactiveUI слишком сложен и плохо ложиться на MV* паттерны. В дикой природе я ReactiveUI не видел.
Обработка сигналов с датчиков — крайне редкая задача в наше время.
Re[7]: RX - живой ли ?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.07.13 15:19
Оценка:
Здравствуйте, ionoy, Вы писали:

I>
I>stream.OpA()
I>      .OpB()
I>      .OpC()
I>


I>и получить асинхронную последовательность, которая ведёт себя так, как ты хочешь. Конечно, теоретически это можно будет перенести на TPL, но выглядеть оно будет не так красиво.


И получится низкоуровневый код вперемешку с лямбдами с вагоном всяких приседаний для связывания.

var a = await stream.OpA();
var b = await stream.OpB(a);
var c = await stream.OpC(b, a);

return a + b + c;
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.