C++/CX : How to expose/convert an existing concurrency::task to Windows::Foundation::IAsyncAction^ ?

, , Comments Off on C++/CX : How to expose/convert an existing concurrency::task to Windows::Foundation::IAsyncAction^ ?

streamVideoBlobWindows81😮 I am really writing a blog post on C++ ? Yest it seems so :). At this year MVP Summit I discovered how much fun I can have with C++ (and especially C++/Cx in my case) thanks to Simon Ferquel and Bruno Boucard.

concurrency::task are available through the “ppltasks.h” header files and can be considered as the TPL tasks in C#.
One of the first thing I tried to do in a C++ component is to create a concurrency::task, use it and expose it as a IAsyncAction to the other C#/JS component.

I often create components which needs initialization, and to do so I create tasks:

  • It will be executed on another thread
  • The “client” does not have to wait for the initialization to complete if they don’t need the component immediately
  • In all my component internal functions, I can wait for the initialization to finish using continuation, if it’s already initialized, it returns immediately

It’s not possible to expose a PPL concurrency::task as a WinRT IAsyncAction. To create and return an IAsyncAction, you have to use the concurrency::create_async function which internally create a task and wraps it. If the passed lambda returns a type, then the create_async will return a IAsyncOperation (isn’t it wonderful ?). Here is an example :
[cpp]
concurrency::create_async([this](){ /* my job to do in a task /* });
[/cpp]

But in my case, the task is already created. So the only solution I found to this issue is to create a lambda which returns my task and feed the create_async method with it. As the lambda returns a task, the create_async will create a IAsyncAction/Operation which will wait for the completion of the init task too.

[cpp]
Windows::Foundation::IAsyncAction^ YoupiTralala::ForceInitAsync()
{
auto toReturn= concurrency::create_async([this](){ return this->initTask;});
return toReturn;
}
[/cpp]

Interesting links:

Do you know a better way to do this ?