Здравствуйте, artelk, Вы писали:
A>Что-нибудь, что позволяет выпрямить такой код:
A>...
A>А в идеале, чтоб, если захочется, еще можно было, например, завернуть все в try/catch:
A>...
Если цель именно "выпрямлять", то по идее ничего кроме какой-то разновидности сопрограмм и не поможет. Моя же мысль была в том, что кроме "лапшевидного" и "выпрямленного" кода, могут быть и другие удобные варианты. Кроме уже упомянутых акторов можно вспомнить ещё и организацию обработки сообщений в классических ООП фреймворках (когда весь управляющий код скрыт где-то внутри, а пользователь библиотеки просто переопределяет пару нужных функций у наследуемого класса, которые будут сами вызваны фреймворком в нужный момент). Или например если взять машину состояний с нетривиальной реализацией (типа такого
http://www.boost.org/doc/libs/1_56_0/libs/msm/doc/HTML/ch03s04.html#d0e1462 например). Да мало ли ещё вариантов. Не вижу особой потребности именно в линеаризации параллельного кода.
_>>Оно конечно длиннее, но лично мне больше нравится по ряду причин.
A>Кто и как вызывает OnData? Что за ряд причин?
Главный цикл обработки сообщений UI потока. Т.е. это универсальный код, реализованный даже не под приложение, а вообще на уровне фреймворка.
А причины, как я уже сказал, исключительно субъективные и эстетические — мне не нравится, что на самом деле нелинейный код (в реальности там возникает "разрыв", в котором может происходить что угодно) визуально старается притвориться линейным. На мой вкус подобное затрудняет полноценное понимание кода. Вообще у меня есть подозрение, что например многие пользователи await из .Net очень слабо представляют себе процессы, происходящие при этом внутри.
A>Блин, ты пойми, я не только такты считаю, я хочу, чтоб все ядра использовались и IO асинхронный был, но, при этом, код в спагетти не размотало.
Ну так и какие проблемы с многоядерностью у вышеуказанных инструментов? )
A>Вот, например, сделаешь ты зеленые потоки в одном системном потоке — остальные ядра будут проставивать, даже когда работа есть, запросы новые идут.
Так почему я в одном то сделаю, а не на пуле? )
A>Asynchronous completion handlers will only be called from threads that are currently calling io_service::run()
A>Подозреваю, что тут лишний перескок из IOCP thread, не?
Вот тут
http://www.boost.org/doc/libs/1_56_0/doc/html/boost_asio/overview/core/async.html есть картинка, которая очень хорошо всё поясняет. )
_>>Но опять же надо понимать, что даже такая крайне эффективная реализации сопрограмм всё равно имеет определённые накладные расходы. Так что если уж производительность уж совсем критична, то лучше забыть про сопрограммы. И кстати не такой уж и страшный код без них выходит. )))
A>От boost.asio тоже придется отказаться?
Нет, в boost.asio сразу много разных вариантов использования заложено. И кстати вариант на базе Boost.Coroutine вроде не так давно появился.