Raymond Chen explains why C++/WinRT does not allow multiple awaits on asynchronous operations like C#, JavaScript, and Python do, citing the lack of a standard library task type and the principle of not paying for unused functionality.
<p>The Windows Runtime expresses asynchronous execution in the form of types like <code>IAsyncOperation</code>. Different languages choose to represent this concept in different ways.</p>
<ul>
<li>C# wraps it inside a <code>System.<wbr />Threading.<wbr />Tasks.<wbr />Task</code>.</li>
<li>JavaScript wraps it inside a <code>Promise</code>.</li>
<li>Python wraps it inside an <code>asyncio.<wbr />Future</code>.</li>
</ul>
<p>All of the above wrappers support multiple continuations, which means that you can call <code>await</code> on them multiple times.</p>
<p>But C++/WinRT doesn’t provide such a wrapper. C++/WinRT just exposes the original <code>IAsyncOperation</code>. The <code>IAsyncOperation</code> doesn’t allow multiple continuations to be attached, so you cannot <code>co_await</code> it multiple times.</p>
<p>Boo.</p>
<p>Why doesn’t C++/WinRT get with the program and provide a wrapper that supports multiple continuations?</p>
<p>Well, one reason is that C#’s <code>System.<wbr />Threading.<wbr />Tasks.<wbr />Task</code>, JavaScript’s <code>Promise</code>, and Python’s <code>asyncio.<wbr />Future</code> are part of the respective languages’ standard libraries. This makes them an obvious choice for projection since they are a way to represent asynchronous execution that is universally understood by anybody writing code in that language. Furthermore, the fact that they are standard library features lets the projections build on the work of others: The standard library maintainers have already implemented, tested, and optimized these classes.</p>
<p>C++ does not have a standard library for asynchronous execution. Instead, C++ provides raw materials out of which you can write your own library. And we wrote one such library <a title="A map through the three major coroutine series" href="https://devblogs.microsoft.com/oldnewthing/20210504-01/?p=105178"> back when we learned about C++ coroutines</a> and implemented a <code>simple_task</code> class.</p>
<p>The lack of a standard library <code>task</code> type means that there isn’t a pre-existing wrapper that C++ projections could take advantage of. It’s every man for himself.</p>
<p>C++/WinRT provides a minimal coroutine promise for <code>IAsyncOperation</code> in deference to the general C++ principle of “you don’t pay for what you don’t use.” The overwhelming majority of the time, you have no need to await an <code>IAsyncOperation</code> more than once, so why make every <code>IAsyncOperation</code> pay for it?</p>
<p>Next time, we’ll look at a case where you would want to await an <code>IAsyncOperation</code> more than once, and see what we can do to work around the C++/WinRT limitation.</p>
<p><b>Bonus chatter</b>: There does exist a pre-existing library that supports multiple continuations: The Parallel Patterns Library <code>concurrency::<wbr />task</code> object. The older C++/CX projection does not natively wrap the <code>IAsyncOperation^</code>, but the Parallel Patterns Library does have special knowledge of the C++/CX <code>IAsyncOperation^</code>, so you can wrap an <code>IAsyncOperation^</code> inside a PPL <code>task</code> and <code>co_await</code> the <code>task</code> more than once.</p>
<p>So I guess you could say that somebody already wrote the wrapper for you. Unfortunately, that wrapper is quite bulky because the PPL library has <i>so many features</i>, most of which you probably aren’t using. You could say that while C++/WinRT tries to be minimalist, PPL tries to be maximalist. It’s easier to start small and grow and it is to start big and try to pare back. (And C++/WinRT generally delegates the “grow” part to the Windows Implementation Library, which adds additional features with headers like <tt>cppwinrt_helpers.h</tt> and <tt>cppwinrt_authoring.h</tt>.)</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260526-00/?p=112354">If C# and JavaScript lets me await a Windows Runtime asynchronous operation more than once, why not C++/WinRT?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
# If C# and JavaScript lets me await a Windows Runtime asynchronous operation more than once, why not C++/WinRT? - The Old New Thing
Source: [https://devblogs.microsoft.com/oldnewthing/20260526-00?p=112354](https://devblogs.microsoft.com/oldnewthing/20260526-00?p=112354)
The Windows Runtime expresses asynchronous execution in the form of types like`IAsyncOperation`\. Different languages choose to represent this concept in different ways\.
- C\# wraps it inside a`System\.Threading\.Tasks\.Task`\.
- JavaScript wraps it inside a`Promise`\.
- Python wraps it inside an`asyncio\.Future`\.
All of the above wrappers support multiple continuations, which means that you can call`await`on them multiple times\.
But C\+\+/WinRT doesn’t provide such a wrapper\. C\+\+/WinRT just exposes the original`IAsyncOperation`\. The`IAsyncOperation`doesn’t allow multiple continuations to be attached, so you cannot`co\_await`it multiple times\.
Boo\.
Why doesn’t C\+\+/WinRT get with the program and provide a wrapper that supports multiple continuations?
Well, one reason is that C\#’s`System\.Threading\.Tasks\.Task`, JavaScript’s`Promise`, and Python’s`asyncio\.Future`are part of the respective languages’ standard libraries\. This makes them an obvious choice for projection since they are a way to represent asynchronous execution that is universally understood by anybody writing code in that language\. Furthermore, the fact that they are standard library features lets the projections build on the work of others: The standard library maintainers have already implemented, tested, and optimized these classes\.
C\+\+ does not have a standard library for asynchronous execution\. Instead, C\+\+ provides raw materials out of which you can write your own library\. And we wrote one such library[back when we learned about C\+\+ coroutines](https://devblogs.microsoft.com/oldnewthing/20210504-01/?p=105178)and implemented a`simple\_task`class\.
The lack of a standard library`task`type means that there isn’t a pre\-existing wrapper that C\+\+ projections could take advantage of\. It’s every man for himself\.
C\+\+/WinRT provides a minimal coroutine promise for`IAsyncOperation`in deference to the general C\+\+ principle of “you don’t pay for what you don’t use\.” The overwhelming majority of the time, you have no need to await an`IAsyncOperation`more than once, so why make every`IAsyncOperation`pay for it?
Next time, we’ll look at a case where you would want to await an`IAsyncOperation`more than once, and see what we can do to work around the C\+\+/WinRT limitation\.
**Bonus chatter**: There does exist a pre\-existing library that supports multiple continuations: The Parallel Patterns Library`concurrency::task`object\. The older C\+\+/CX projection does not natively wrap the`IAsyncOperation^`, but the Parallel Patterns Library does have special knowledge of the C\+\+/CX`IAsyncOperation^`, so you can wrap an`IAsyncOperation^`inside a PPL`task`and`co\_await`the`task`more than once\.
So I guess you could say that somebody already wrote the wrapper for you\. Unfortunately, that wrapper is quite bulky because the PPL library has*so many features*, most of which you probably aren’t using\. You could say that while C\+\+/WinRT tries to be minimalist, PPL tries to be maximalist\. It’s easier to start small and grow and it is to start big and try to pare back\. \(And C\+\+/WinRT generally delegates the “grow” part to the Windows Implementation Library, which adds additional features with headers likecppwinrt\_helpers\.handcppwinrt\_authoring\.h\.\)
### Category
### Topics
## Author

Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.
The article discusses a C++/WinRT pattern for caching the result of a Windows Runtime IAsyncOperation, including handling failures, so that multiple coroutines can share the cached result or exception.
ClojureScript 1.12.145 introduces native async function support via the ^:async hint, enabling direct JavaScript async/await interop without additional dependencies.
This article explains how to use Win32 structures in the Windows Runtime by declaring shadow structures with the same layout, including specific examples and alternatives for common structures.
A technical blog post exploring Rust async programming on ARM architecture using the ARM generic timer, comparing timer peripherals and discussing frameworks like Embassy and RTIC.