Здравствуйте, Ikemefula, Вы писали:
N_P>>Потребность, собственно, как раз в обработке потока пакетов данных, частным случаем которого являются очереди сообщений. Без написания велосипедов. Потому что правильный велосипед для решения этой задачи должен уметь как минимум фильтрацию, агрегацию, ограниченную буферизацию и обработку ошибок. Быть неблокирующим, многопоточным и не жрать ресурсы в бездействии. Очень непростой велосипед.
I>Практически все это короутины умеют искаропки.
Но, как я понимаю — на .NET их нет ? Готовых, стабильных и понятных ?
Здравствуйте, Nikolay_P_I, Вы писали:
I>>Практически все это короутины умеют искаропки.
N_P>Но, как я понимаю — на .NET их нет ? Готовых, стабильных и понятных ?
Здравствуйте, 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.
N_P>>Пока я знаю 2 более-менее подходящих готовых варианта решения — TPL Workflow и RX. Вот и спрашиваю — кто из них как поживает I>"я уже два с половиной раза прочёл Introduction to RX, но всё равно частенько встречаюсь с вещами, которые мне непонятны. То есть порог вхождения у него достаточно высокий." I>И это пишет человек который во всю злоупотребляет Немерле на каждом шагу
Это совсем не обязательно означает, что RX плох. Просто сама концепция для меня была достаточно нова, а так как там есть операторы, которые выполняют сложную логику, то конечно сходу так и не въедешь во всё.
Опять же, я не говорю, что RX идеален. Там, много недостатков, которые являются следствием ограниченности C#. Но если наберёшься достаточно опыта, то сложно найти инструмент более мощный и универсальный.
Всё как с Немерле
Здравствуйте, 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
Большая часть описанных проблем уже решена в готовых библиотеках. Да и такого уровня задачи встречаются нечасто (на моей памяти такого вообще не было).
А на TPL Workflow задачу решать не пробовали ? Именно WorkFlow, там, вроде, есть функционал продолжения и оно вообще на RX местами похоже.
G>Большая часть описанных проблем уже решена в готовых библиотеках. Да и такого уровня задачи встречаются нечасто (на моей памяти такого вообще не было).
А какие библиотеки есть ? Что посмотреть ?
А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений.
Здравствуйте, 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 используют. Он внутри весь на тасках.
Здравствуйте, 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.
Это все не то. Вопрос не в монадах. Вопрос в обвязке. Буфера, отмена, агрегаты исключений. А если самом у все это писать — проще сразу на TPL. Знакомее.
N_P>>А задачи — ящиками! Простейшая и вездесущая — прием пакетов данных по TCP\IP, десериализация, фильтрация, выполнение, возвращение результата. С отменой, паузой, буфером, обработкой ощибок и разными типами данных. Быстро и многопоточно. Классика. Обработка очереди сообщений. G>Это как раз кейс для Rx. Увы такие вещи мало кто пишет. Все работают уровнем выше, например webapi используют. Он внутри весь на тасках.
А если данные от датчиков ? А если это документооборот ? Не Webом же единым.
Здравствуйте, 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.
Здравствуйте, 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ом же единым.
А зачем в документообороте вообще такое?
Здравствуйте, gandjustas, Вы писали:
G>Во многих случаях быстрее и выгоднее написать на TPL, чем на Rx.
Какое то очень странное противопоставление. Rx никоим образом не претендует на замену TPL, более того, асинхронная часть в нем как раз поверх TPL и построена.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, gandjustas, Вы писали:
G>>Во многих случаях быстрее и выгоднее написать на TPL, чем на Rx.
AVK>Какое то очень странное противопоставление. Rx никоим образом не претендует на замену TPL, более того, асинхронная часть в нем как раз поверх TPL и построена.
В RX concurrency построена поверх свой абстракции IScheduler. Реализация IScheduler может быть и на тасках, но паттерн использования тасков в этом случае отличается от того, под что затачивается TPL. Поэтому при примерно одинаковом коде Rx таки медленнее, хотя в реальных случаях с реальным IO это разница будет незаметна.
Я не писал что Rx претендует на замену TPL. Скорее наоборот. Rx исторически раньше появился в "широком доступе". Но после появления async\await потребность в нем резко упала.
Здравствуйте, gandjustas, Вы писали:
G>Я не писал что Rx претендует на замену TPL. Скорее наоборот. Rx исторически раньше появился в "широком доступе". Но после появления async\await потребность в нем резко упала.
Честно говоря, для меня async/await вообще не пересекается с RX. Если await — это грубо говоря сахар для ContinueWith, то RX — это средство управления потоками событий/данных и т.д. Я не вижу в TPL инструментов для работы с последовательностями.
Здравствуйте, 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 окупаются (в основном затраты на то чтобы разобраться как оно работает).
Здравствуйте, 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 в целом, которые сближают наш опыт работы в одном потоке и программирование в асинхронном мире.
Здравствуйте, 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 не видел.
Обработка сигналов с датчиков — крайне редкая задача в наше время.
I>и получить асинхронную последовательность, которая ведёт себя так, как ты хочешь. Конечно, теоретически это можно будет перенести на TPL, но выглядеть оно будет не так красиво.
И получится низкоуровневый код вперемешку с лямбдами с вагоном всяких приседаний для связывания.
var a = await stream.OpA();
var b = await stream.OpB(a);
var c = await stream.OpC(b, a);
return a + b + c;