Re[37]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 02:34
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>На stackfull короутинах здесь не было ни одного примера асинхронщины. Ни одного, зато есть вопли, как всё просто и шоколадно. Есть мой пример с message pump — допили его и продемонстрируй асинхронщину


Да легко. В начале для наглядности исходный (синхронный блокирующий) код:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
    AttachConsole();
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)>0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

void SomeMessageHandler()
{
    wstring buf;
    getline(wcin, buf);
    wcout<<L"Эхо: "<<buf;
}


И его асинхронный вариант:
AsyncPool async_pool;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
    AttachConsole();
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)>0){
        async_pool.RunAll();
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

void SomeMessageHandler()
{
    async_pool.Add([=](AsyncPool::This& this_async){//эти две строки можно для красоты запрятать
        wistream async_wcin(new АsyncBuf(this_async, wcin.rdbuf()));//в макрос :D
        wstring buf;
        getline(async_wcin, buf);
        wcout<<L"Эхо: "<<buf;
    });
}


Насколько я понимаю (хотя я не особо разбирался — может поправишь меня?), написать подобный однопоточный код на C# без модификации функции getline и класса wistream нереально. Ну а тут как видишь без проблем пишется.

Ну и реализации async классов (по сути всё тоже самое что и в моих предыдущих примерах тут, только чуть формальнее):
class AsyncPool{
    using Coro=boost::coroutines::coroutine<void()>;
    list<Coro> coro_list;
public:
    using This=Coro::caller_type;
    template<typename L> void Add(L l) {coro_list.emplace_back(l);}
    void RunAll()
    {
        for(auto& c: coro_list) c();
        coro_list.remove_if([](const Coro& c) {return !c;});
    }
}

class АsyncBuf: public wstreambuf{
AsyncPool::This& this_async;
wstreambuf* sync_buf;
public:
    АsyncBuf(AsyncPool::This& c, wstreambuf* sb): this_async(c), sync_buf(sb){}
    wchar_t getc()//псевдокод, т.к. я не помню реальный api у std::streambuf
    {
        while(!sync_buf->is_avail()) this_async();
        return sync_buf->getc();
    }
};


I>Пока что очевидно, что вызов любого метода из message pump приведет замораживанию приложения. Что бы это забороть, надо явно делать короутинами вообще всё, в т.ч. и message pump. То есть на ровном месте педалить и приседать с кооперативной многозадачностью.


Как видишь ничего подобного. )))

I>Смешно — короутины есть в современных OS с незапамятных времен и как то это никак не сказалось на асинхронщине


Потому как реально эта самая асинхронщина (не путаем с нормальным многопоточным кодом) очень мало где нужна.
Re[38]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 03:13
Оценка:
Да, кстати, для сравнения можно ещё и многопоточный вариант твоего кода представить:
AsyncPool async_pool;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
    AttachConsole();
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)>0){
        async_pool.RunAll();
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

void SomeMessageHandler()
{
    async_pool.Add([=](AsyncPool::This& this_async){//эти две строки можно для красоты
        auto r=await_async(this_async, [&](){//запрятать в макрос :D
            wstring buf;
            getline(wcin, buf);
            return buf;
        });
        wcout<<L"Эхо: "<<r;
    });
}

Но это скучный (т.к. он на C# без проблем пишется , да и некорректный (если несколько getline'ов будут параллельно бороться за ввод пользователя) вариант.
Re[37]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 03:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Если всё что нужно это сделать фоновую скачку файла, то вполне могу себе представить ситуацию, где даже при наличии await'а — вместо него будет использоваться явный код с .then'ом, указанием ui контекста и т.п., ибо очевидно что у await'а есть свой порог вхождения, а код не только пишется, но ещё и обслуживается, причём зачастую разными людьми. Например тот же Ikemefula, который бьёт себя пяткой в грудь что заменит целый взвод азиатов, уже неделю не может понять как можно использовать stackful coroutine. Тогда чего уж там говорить о "типичных" программистах.


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

На мой вкус подобные техники реально полезны в двух случаях:
1. Написание библиотек, которые должны работать в двух режимах (синхронный и асинхронный) — тут естественно это должно быть замечательным решением без избыточного кода. Хотя пока реальных примеров не видел.
2. Случаи когда нам требуются много тысяч параллельных задач.

Может и ещё что-то есть, что сейчас в голову не пришло. А во всех остальных задачах на мой вкус проще, нагляднее и эффективнее использовать классическое многопоточное программирование.
Re[38]: Что посоветуете как аналог С++
От: Mazay Россия  
Дата: 28.06.13 10:46
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И его асинхронный вариант:

_>
_>AsyncPool async_pool;

_>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
_>{
_>    AttachConsole();
_>    MSG msg;
_>    while(GetMessage(&msg, NULL, 0, 0)>0){
_>         async_pool.RunAll();
_>        TranslateMessage(&msg);
_>        DispatchMessage(&msg);
_>    }
_>    return msg.wParam;
_>}

_>void SomeMessageHandler()
_>{
_>    async_pool.Add([=](AsyncPool::This& this_async){//эти две строки можно для красоты запрятать
_>        wistream async_wcin(new АsyncBuf(this_async, wcin.rdbuf()));//в макрос :D
_>        wstring buf;
_>        getline(async_wcin, buf);
_>        wcout<<L"Эхо: "<<buf;
_>    });
_>}
_>


В принципе работать будет но могут быть осложнения:
1. Если сообщения не приходят достаточно часто, то и вызов async_pool.RunAll(); будет необоснованно задерживаться.
2. Вызов async_pool.RunAll(); может долго не отдавать управление, если асинхронные операции долго не завершаются. Он же там ждёт на select() каком-нибудь.

Строго однопоточное и неблокирующееся решение состоит в использовании MsgWaitForMultipleObjects() под виндой и использовании хэндлера ConnectionNumber() под X Window.
А правильное решение состоит в использовани отдельного потока для GUI.
Главное гармония ...
Re[38]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 11:02
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И его асинхронный вариант:

_>
_>AsyncPool async_pool;

_>void SomeMessageHandler()
_>{
_>    async_pool.Add([=](AsyncPool::This& this_async){//эти две строки можно для красоты запрятать
_>        wistream async_wcin(new АsyncBuf(this_async, wcin.rdbuf()));//в макрос :D
_>        wstring buf;
_>        getline(async_wcin, buf);
_>        wcout<<L"Эхо: "<<buf;
_>    });
_>}
_>


_>Насколько я понимаю (хотя я не особо разбирался — может поправишь меня?), написать подобный однопоточный код на C# без модификации функции getline и класса wistream нереально. Ну а тут как видишь без проблем пишется.


То есть, снова появляется или функция или макрос, то есть, наружу торчат асинхронные кишки ?

_>Ну и реализации async классов (по сути всё тоже самое что и в моих предыдущих примерах тут, только чуть формальнее):

_>
_>class AsyncPool{
_>    using Coro=boost::coroutines::coroutine<void()>;
_>    list<Coro> coro_list;
_>public:
_>    using This=Coro::caller_type;
_>    template<typename L> void Add(L l) {coro_list.emplace_back(l);}
_>    void RunAll()
_>    {
_>        for(auto& c: coro_list) c();
_>        coro_list.remove_if([](const Coro& c) {return !c;});
_>    }
_>}

Где вызов RunAll ?

_>class АsyncBuf: public wstreambuf{
_>AsyncPool::This& this_async;
_>wstreambuf* sync_buf;
_>public:
_>    АsyncBuf(AsyncPool::This& c, wstreambuf* sb): this_async(c), sync_buf(sb){}
_>    wchar_t getc()//псевдокод, т.к. я не помню реальный api у std::streambuf
_>    {
_>        while(!sync_buf->is_avail()) this_async();
_>        return sync_buf->getc();
_>    }
_>};
_>


И снова не совсем ясно,
1 как вернется управление к моему message pump
2 когда будет получать управление диспетчер короутин

I>>Пока что очевидно, что вызов любого метода из message pump приведет замораживанию приложения. Что бы это забороть, надо явно делать короутинами вообще всё, в т.ч. и message pump. То есть на ровном месте педалить и приседать с кооперативной многозадачностью.


_>Как видишь ничего подобного. )))


Я пока что вижу в лучшем случае надо писать ровно то же, только руками строить короутину. В C# нужно писать async-await, а у тебя макры

I>>Смешно — короутины есть в современных OS с незапамятных времен и как то это никак не сказалось на асинхронщине

_>Потому как реально эта самая асинхронщина (не путаем с нормальным многопоточным кодом) очень мало где нужна.

Да как бы наоборот — асинхронщина нужна везде и всегда.
Re[41]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 12:11
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


I>>>>Возьми любой мой пример, я ажно пять вариантов привел. Только должно быть явно обозначено, как будет вызываться message pump. И message pump именно мой, а не просто какой то эвентлуп для короутин.

EP>>>Ты понимаешь что такое полностью рабочий пример? Это не те огрызки которые ты тут приводил.
I>>Внятно ответь на вопросы
I>>1 — как получит управление МОЙ message pump.
I>>2 — как message pump передаст управление короутине когда процессинг закончится.

EP>Зависит от того какую асинхронную операцию и как (по какому событию) ты собрался выполнять, поэтому и прошу привести полный пример.



case WM_USER: // все прост, никаких фокусов
  textBox.text += await handler();
  break;


операция примерно такая, аналог на с# чз AsyncCallback, AsyncResult и тд.

string async handler()
{
  var http = new Http("some url");
  var result = await Task.FromBeginEnd(asyncCallback)=>http.BeginRead(asyncCallback), (asyncResult)=>http.EndRead(asyncResult) );

  return string;
}



I>>Условно считаем так — есть message pump и есть ровно один хандлер который вызывается этим message pump. От тебя требуется показать что нибудь предельно простое, асинхронное, которое реализовано унутре этого хандлера.


EP>Видимо конкретного кода я не дождусь. Давай тогда так:

EP>Я только добавивлю include корутин, и сделаю трансформацию описанную выше внутри task.
EP>Такой пример подойдёт?

Не ясно, что за трансформацию ты собираешься делать внутри таска. Если всю асинхронщину, то её надо делать в хандлере.

I>>Пока что ты продемонстрировал замерзание UI.


EP>Где?


Твой код останавливает message pump и нигде не было показано как этот памп будет продолжен.
Re[42]: Что посоветуете как аналог С++
От: Evgeny.Panasyuk Россия  
Дата: 28.06.13 12:50
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>Зависит от того какую асинхронную операцию и как (по какому событию) ты собрался выполнять, поэтому и прошу привести полный пример.

I>
I>case WM_USER: // все прост, никаких фокусов
I>  textBox.text += await handler();
I>  break;
I>


покажи полный код

I>Не ясно, что за трансформацию ты собираешься делать внутри таска. Если всю асинхронщину, то её надо делать в хандлере.


Так подойдёт? Всё в хендлере:
#include <boost/coroutine/all.hpp>
#include <functional>
#include <algorithm>
#include <cstring>
#include <memory>
using namespace std;

#include <windows.h>

function<void()> on_minization;

template<typename F>
void async_something(F f)
{
    on_minization = f;
}

void task()
{
    MessageBox(0, TEXT("on max"), TEXT(""), MB_OK);
    async_something([]
    {
        MessageBox(0, TEXT("on min"), TEXT(""), MB_OK);
    });
}

LRESULT CALLBACK window_procedure(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
    switch (msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_SIZE:
            switch(w_param)
            {
                case SIZE_MAXIMIZED:
                    task();
                    break;
                case SIZE_MINIMIZED:
                    if(on_minization) on_minization();
                    break;
            }
        default:
            return DefWindowProc(hwnd, msg, w_param, l_param);
    }
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
    WNDCLASS wincl = {};
    wincl.hInstance = hInstance;
    wincl.lpszClassName = TEXT("SFC");
    wincl.lpfnWndProc = window_procedure;
    RegisterClass(&wincl);

    auto hwnd = CreateWindow(wincl.lpszClassName, TEXT(""), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, 0);
    ShowWindow (hwnd, nCmdShow);

    MSG msg;
    while(GetMessage(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

task переписывается на корутины без каких-либо изменений остального кода
Re[39]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 12:50
Оценка:
Здравствуйте, Mazay, Вы писали:

M>В принципе работать будет но могут быть осложнения:

M>1. Если сообщения не приходят достаточно часто, то и вызов async_pool.RunAll(); будет необоснованно задерживаться.

Ага, точно, надо MsgWaitForMultipleObjects. Ну собственно я то в любом случае не стал бы писать такой код, а это было по запросу Ikemefula на его примере. Я то написал бы просто
void SomeMessageHandler()
{
    thread([=](){
        wstring buf;
        getline(wcin, buf);
        PostMessage(buf);
    }.detach();
}



M>2. Вызов async_pool.RunAll(); может долго не отдавать управление, если асинхронные операции долго не завершаются. Он же там ждёт на select() каком-нибудь.


Нет, там нет ничего блокирующего вообще.

M>А правильное решение состоит в использовани отдельного потока для GUI.


Нуу да, правда формулировка какая-то нестандартная. Чаще же основной поток как раз для GUI и куча отдельных для какой-то работы.
Re[39]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 13:07
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>То есть, снова появляется или функция или макрос, то есть, наружу торчат асинхронные кишки ?


Ну так кишки то по любому есть и в C++ и в C#. Фишка данного кода в том, что мы используем обычную синхронную блокирующую функцию getline в асинхронном однопоточном режиме без всякой её модификации.

I>Где вызов RunAll ?


В главном цикле же.

I>И снова не совсем ясно,

I>1 как вернется управление к моему message pump

Handler возвращает управление немедленно при любом раскладе.

I>2 когда будет получать управление диспетчер короутин


Когда будут пробегать сообщения в главном цикле. В принципе Mazay уже правильно указал, что просто GetMessage тогда тут некорректно и надо поправить главный цикл чтобы он крутился не только по обычным сообщениям.

I>Я пока что вижу в лучшем случае надо писать ровно то же, только руками строить короутину. В C# нужно писать async-await, а у тебя макры


Хыхыхы, если речь конкретно про этот код, то его аналог на C# вообще не написать никак. Так что до сравнения стилистических нюансов дело как бы вообще не должно доходить. )))

I>Да как бы наоборот — асинхронщина нужна везде и всегда.


Ну это смотря что под ней подразумевать... Например такой код
thread([=](){
    PostMessage(Download(url));
}).detach();

это всё ещё асинхронщина или уже нет? )))
Re[43]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 13:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>покажи полный код


Это будет 100-200кб которые я выдеру из декомпиленой сборки. Тебя это устроит ?

Можешь сделать все что угодно, ожидание UI запущеного приложение, ожидание какого либо объекта ядра — все что угодно, только не бустовскую хрень, где это все упаковано хрен знает куда.

EP>task переписывается на корутины без каких-либо изменений остального кода


Мне нужно что бы ты показал
1 где будет ожидание результата
2 как управление вернется в message pump
2 как управление будет передаваться в твой шедулер или короутину
Re[44]: Что посоветуете как аналог С++
От: Evgeny.Panasyuk Россия  
Дата: 28.06.13 13:31
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>task переписывается на корутины без каких-либо изменений остального кода

I>Мне нужно что бы ты показал
I>1 где будет ожидание результата

Тут ожидание события SIZE_MINIMIZED.

I>2 как управление вернется в message pump


После вызова async_something

I>2 как управление будет передаваться в твой шедулер или короутину


По событию, так же как в примере с task выше.
Подходит?
Re[45]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 13:47
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>task переписывается на корутины без каких-либо изменений остального кода

I>>Мне нужно что бы ты показал
I>>1 где будет ожидание результата

EP>Тут ожидание события SIZE_MINIMIZED.


Не надо такое.

I>>2 как управление вернется в message pump


EP>После вызова async_something


I>>2 как управление будет передаваться в твой шедулер или короутину


EP>По событию, так же как в примере с task выше.

EP>Подходит?

Сделай ожидание какого нибудь объекта ядра или еще чего навроде.
Re[40]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 13:56
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Где вызов RunAll ?

_>В главном цикле же.

Выдели жирным, взял из твоего кода этот самый главный цикл
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
    AttachConsole();
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)>0){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}



I>>2 когда будет получать управление диспетчер короутин

_>Когда будут пробегать сообщения в главном цикле. В принципе Mazay уже правильно указал, что просто GetMessage тогда тут некорректно и надо поправить главный цикл чтобы он крутился не только по обычным сообщениям.

Шота у тебя и EP показания не сходятся

I>>Я пока что вижу в лучшем случае надо писать ровно то же, только руками строить короутину. В C# нужно писать async-await, а у тебя макры


_>Хыхыхы, если речь конкретно про этот код, то его аналог на C# вообще не написать никак. Так что до сравнения стилистических нюансов дело как бы вообще не должно доходить. )))


Цель, понятное дело, написать так как нельзя в сишарп а не решить конкретную проблему ?

I>>Да как бы наоборот — асинхронщина нужна везде и всегда.


_>Ну это смотря что под ней подразумевать...


Да все как везде — скачивание, обращение к базе, устройству и тд и тд и тд и тд и тд и тд и тд
Re[46]: Что посоветуете как аналог С++
От: Evgeny.Panasyuk Россия  
Дата: 28.06.13 14:04
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>>>1 где будет ожидание результата

EP>>Тут ожидание события SIZE_MINIMIZED.
I>Не надо такое.

Почему? Чем отличается от "ожидания результата" в данном контексте?

I>>>2 как управление будет передаваться в твой шедулер или короутину

EP>>По событию, так же как в примере с task выше.
EP>>Подходит?
I>Сделай ожидание какого нибудь объекта ядра или еще чего навроде.

Не увиливай, чем тебе minimize event не подходит?
Re[47]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 16:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

I>>>>1 где будет ожидание результата

EP>>>Тут ожидание события SIZE_MINIMIZED.
I>>Не надо такое.

EP>Почему? Чем отличается от "ожидания результата" в данном контексте?


Я чуток запутался, по WM_SIZE будет таск запускаться, тогда нормально. Где будет ожидание результата в task ?
Re[40]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 16:39
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ага, точно, надо MsgWaitForMultipleObjects. Ну собственно я то в любом случае не стал бы писать такой код, а это было по запросу Ikemefula на его примере. Я то написал бы просто


Ага и еще тебе придется таймер подключать к этому.

M>>2. Вызов async_pool.RunAll(); может долго не отдавать управление, если асинхронные операции долго не завершаются. Он же там ждёт на select() каком-нибудь.


_>Нет, там нет ничего блокирующего вообще.


Теперь мы пришли к выводу, что надо патчить Message Pump.

::MessageBox() — вот эта функция похерит всю твою асинхронность по той простой причине, что запускает message pump и ничего не знает про твой RunAll

Теперь задачка посложнее, представь себе, что у тебя нет доступа к Message Pump, как заставить работать твою асинхронность ?

И похоже, что ваша хваленая асинхронность будет дико лагать, т.к. сильно зависит от частоты эвентов в системе и целой кучи других факторов.
Re[48]: Что посоветуете как аналог С++
От: Evgeny.Panasyuk Россия  
Дата: 28.06.13 17:43
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Я чуток запутался, по WM_SIZE будет таск запускаться, тогда нормально.


В первом варианте он был в main, во втором он в хэндлере по WM_SIZE — но суть от этого не меняется.

I>Где будет ожидание результата в task ?


void task()
{
    MessageBox(0, TEXT("on max"), TEXT(""), MB_OK);
    async_something([]
    {
        MessageBox(0, TEXT("on min"), TEXT(""), MB_OK);
    });
}

Во втором statement'е таск запускает асинхронную обработку, и передаёт лямбду-продолжение как параметр, completion callback — т.е. что делать, когда это something (например download) произойдёт.
Re[41]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 18:17
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Выдели жирным, взял из твоего кода этот самый главный цикл


Это ты скопиривал из синхронного кода, а не асинхронного. )))

I>Шота у тебя и EP показания не сходятся


Так он там тогда другую модельку обсуждал.

I>Цель, понятное дело, написать так как нельзя в сишарп а не решить конкретную проблему ?


Вообще то в последнее время дискуссия свернула к вопросу превосходства stackfull coroutines над остальными вариантами. И этот код отлично демонстрирует один из нюансов превосходства: при переходе с синхронного кода на асинхронный нам не требуется менять весь код в стеке вызова, а правится только самый высший и самый низший уровень.

I>Да все как везде — скачивание, обращение к базе, устройству и тд и тд и тд и тд и тд и тд и тд


Ну я же вроде привёл конкретный пример... Снова отмазываемся? )))

Вот это
thread([=](){PostMessage(download(url));}).detach();

"асинхронщина" или же нет?

Если да, то тогда я подпишусь под утверждением что она нужна везде... Правда я привык называть такое самым обычным многопоточным программированием... Но лишнее название не помеха. )))

Если же нет, то тогда формулируй что же такое "асинхронщина" и будем уже разбираться по формулировке нужно оно где-то или нет...
Re[41]: Что посоветуете как аналог С++
От: alex_public  
Дата: 28.06.13 18:51
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Ага и еще тебе придется таймер подключать к этому.


Нет, если использовать MsgWaitForMultipleObjects, то таймер не нужен. Кстати, там даже есть вариант ждать событий с вводом в консоль, так что вообще оптимально для данной задачки выходит.

Ну или же можно действительно таймер сделать и тогда можно оставить старый GetMessage. Но это уже не так оптимально.


I>Теперь мы пришли к выводу, что надо патчить Message Pump.

I>::MessageBox() — вот эта функция похерит всю твою асинхронность по той простой причине, что запускает message pump и ничего не знает про твой RunAll
I>Теперь задачка посложнее, представь себе, что у тебя нет доступа к Message Pump, как заставить работать твою асинхронность ?
I>И похоже, что ваша хваленая асинхронность будет дико лагать, т.к. сильно зависит от частоты эвентов в системе и целой кучи других факторов.

Эээ ты похоже бредишь. ))) Цель всей этой нашей асинхронщины (что в многопоточном, что в однопоточном варианте) в том, что сделать какие-то дела на стороне и вернуть результат в UI поток. Так что в этой задачке при любой схеме (однопоточной/многопоточной) и при любом языке программирования нам надо будет ждать пока UI поток не освободится для обработки асинхронного результата.

Если же нам можно обрабатывать результат не в UI потоке, то это совсем другая задача становится, которая решается вообще элементарно, но вроде как к "асинхронщине" уже совсем никакого отношения не имеет.
Re[42]: Что посоветуете как аналог С++
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.06.13 20:20
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Цель, понятное дело, написать так как нельзя в сишарп а не решить конкретную проблему ?


_>Вообще то в последнее время дискуссия свернула к вопросу превосходства stackfull coroutines над остальными вариантами. И этот код отлично демонстрирует один из нюансов превосходства: при переходе с синхронного кода на асинхронный нам не требуется менять весь код в стеке вызова, а правится только самый высший и самый низший уровень.


Самый высший — это надо контролировать глобальный цикл выборки сообщений или чтото навроде. Этой возможности может и не быть. Даже так — в общем случае её нет. Любое модальное окно порушит всю твою стройную идею.

I>>Да все как везде — скачивание, обращение к базе, устройству и тд и тд и тд и тд и тд и тд и тд


_>Ну я же вроде привёл конкретный пример... Снова отмазываемся? )))


_>Вот это

_>
_>thread([=](){PostMessage(download(url));}).detach();
_>

_>"асинхронщина" или же нет?

Асинхронщина.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.