Page 44 - MSDN Magazine, June 2018
P. 44

C++
Effective Async with
Coroutines and
C++/WinRT
Kenny Kerr
The Windows Runtime has a relatively simple async model in the sense that, like everything else in the Windows Runtime, it’s focused on allowing components to expose async methods and making it simple for apps to call those async methods. It doesn’t in itself provide a concurrency runtime or even anything in the way of building blocks for producing or consuming async methods. Instead, all of that is left to the individual language projections. This is as it should be and isn’t meant to trivialize the Windows Runtime async pattern. It’s no small feat to implement this pattern correctly. Of course, it also means that a developer’s perception of async in the Windows Runtime is very heavily influenced by the developer’s language of choice. A developer who has only ever used C++/CX might, for example, wrongly but understandably assume that async is a hot mess.
The ideal concurrency framework for the C# developer will be different from the ideal concurrency library for the C++ developer. The role of the language, and libraries in the case of C++, is to take
care of the mechanics of the async pattern and provide a natural bridge to a language-specific implementation.
Coroutines are the preferred abstraction for both implementing and calling async methods in C++, but let’s first make sure we understand how the async model works. Consider a class with a single static method that looks something like this:
struct Sample {
Sample() = delete;
static Windows::Foundation::IAsyncAction CopyAsync(); };
Async methods end with “Async” by convention, so you might think of this as the Copy async method. There might be a blocking or synchronous alternative that’s simply called Copy. It’s conceiv- able that a caller might want a blocking Copy method for use by a background thread and a non-blocking, or asynchronous, method for use by a UI thread that can’t afford to block for fear of appearing unresponsive.
At first, the CopyAsync method might seem quite simple to call. I could write the following C++ code:
IAsyncAction async = Sample::CopyAsync();
As you might imagine, the resulting IAsyncAction isn’t actually the ultimate result of the async method, even though it’s the result of calling the CopyAsync method in a traditional procedural manner. The IAsyncAction is the object that a caller might use to wait upon the result synchronously or asynchronously, depending on the situation. Along with IAsyncAction, there are three other
This article discusses:
• Concurrency
• Coroutines
• The thread pool
Technologies discussed:
Windows Runtime, ISO C++17, C++ Coroutines, C++/WinRT
38 msdn magazine


































































































   42   43   44   45   46