Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Bringing await to C++

Download

Right click “Save as…”

Slides (view online)

Modern application development requires asynchronous programming techniques. For C++, this generally involves using libraries employing promises or futures or tasks, a la PPL and std::future. What about adding 'await' to the C++ language itself? It's clear that 'await' has done wonders for C#. What would it look like for C++? How does it work? This detailed walkthrough will show the benefits of using ‘await’ vs. PPL or std::future, dig into it's implementation in VC++, and explain the differences between C++ await and C# await. 

Follow the Discussion

  • felix9felix9 the cat that walked by itself

    wow wow wow

  • Regarding the continuation context of an await, it would be simple to supply the context if await looked more like a function. That is, "await( async_function(), context )" where context is an optional parameter.

  • Marat AbrarovMarat Abrarov

    They know about Asio! The know (and don't make it a secret) about heaviness of side stack creation for runtime memory (heap?) in a scenario of mass (TCP socket server) usage of "await". They even working over solution for such scenario. VC++ team is really great. Thanks a lot.

  • 'wow wow wow' is entirely appropriate, at the moment you need to take a dependency on C# and interop to native which is obviously horrible ( all that extra machinery and runtime overhead ). Just hope there's going to be a Visual Studio 2014 so we can get await for C++ into production with a go-live licence as soon as possible. It's too yummy to keep in the labs.

    Then we need the ISO folks to include it in C++ 17.

  • Very interesting -- can we expect it in a CTP?  Are parameters to async functions captured and propagated to the side stack? Does this imply a change to the ABI?

  • Thanks for the comments everyone!

    Akhare, yes, we are trying to target the next CTP.

    Parameters to the async function are indeed captured and propagated to the side stack, but it happens inside a trampoline function. The trampoline function thus ensures that there isn't a change in ABI required. i.e. A caller can treat:  "task<T> func() resumable" the same as "task<T> func()".

    In fact, we don't currently have a specific need to put "resumable" on declarations - only on definitions. Hence, it's theoretically completely transparent to callers. We however will require it on declarations for now, just in case. It's easier to remove such a requirement later - not so easy to add it. We've imagined some optimizations if the caller knows it is calling into a resumable function (which will require it on declaration, and thus imply an ABI change), but nothing really concrete.

  • @tomkirbygreen

    4 years plus the time that at least intel, gcc, clang and vc++ support it, are too long in computer time.

    Who knows how the computing landscape will look like in 2020, time the C++17 should be available in mainstream compilers, maybe.

  • shaoyuan1943shaoyuan1943

    Interesting!thank you!

  • MikhailMikhail

    You can write a library that does 'await'.

    Please check this - http://habrahabr.ru/post/185706/

    All you need is this code:

    using __Coro=boost::coroutines::coroutine<void()>;
    void Post2UI(const void* coro);
    template<typename L> auto __await_async(const __Coro* coro, __Coro::caller_type& yield, L lambda)->decltype(lambda())
    {
    auto f=async(launch::async, [=](){
    auto r=lambda();
    Post2UI(coro);
    return r;
    });
    yield();
    return f.get();
    }
    void CallFromUI(void* c)
    {
    __Coro* coro=static_cast<__Coro*>(c);
    (*coro)();
    if(!*coro) delete coro;
    }
    #define async_code(block) { __Coro* __coro=new __Coro; *__coro=__Coro([=](__Coro::caller_type& __yield){block});}
    #define await_async(l) __await_async(__coro, __yield, l)

    Plus GUI-specific implementation of two functions - Post2UI and OnAsync, that need to be written once for the whole application on given GUI framework. (It doesn't need to be GUI, it might be somethig like boost::asio::io_service).

  • Full emulation of await feature from C# language in C++ based on Stackful Coroutines from Boost.Coroutine library: https://github.com/panaseleus/await_emu

    int bar(int i)
    {
    auto result = await boost::async([i]{ return reschedule(), i*100; });
    // await "transforms" rest of code into continuation and attaches it to boost::future::then
    // (any other mechanism similar to .then can be used)
    return result + i*10;
    }

    This proof-of-concept shows that exact syntax of await feature can be emulated with help of Stackful Coroutines, demonstrating that it is superior mechanism.

  • fjestisfjestis

    How await concept relates to Haskell "bind" and "then" operators used in monads, namely `>>=` and `>>`? Both concepts lead to pretty similar thing I think, especially that iterator-based co-routines.

  • GREAT!
    I've tried to use __await/__resumable on C++/CX StoreApp, works fine!

    - f.fukuda, Japan, MVP for Visual C++

  • stepik777stepik777

    Resumable functions are like do-notation in Haskell (and await is like <-). But for one specific monad - std::future.

  • See this blog post for some examples of await:

    http://blogs.msdn.com/b/vcblog/archive/2013/12/20/asynchronous-programming-in-c-using-resumable-functions-and-await.aspx

     

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.