C++/WinRT: Can I await a single IAsyncAction handle from multiple coroutine calls?

Viewed 493

I have coroutine IAsyncAction Foo, Which will be called once at the start of my program.

I also have coroutine IAsyncAction Bar which will be called multiple times, arbitrarily, and must await for Foo at some point.

Can the multiple calls to Bar await for a single call of Foo like this?

IAsyncAction m_fooAction = Foo();

(Later, within Bar...)

co_await m_fooAction;

I tried this, but I keep getting an error: A delegate was assigned when not allowed (see https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/error-handling/hresult-illegal-delegate-assignment).

Please note: This development is for a Windows 8 Desktop app, so can't use CoreDispatcher nor DispatcherQueue.

1 Answers

According to C++/WinRT authors, IAsyncAction and similar interfaces can only have one awaiter.

As an alternative, they recommend using a kernel handle. https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/concurrency-2#awaiting-a-kernel-handle

Update: From Raymond Chen (MSFT):

Possible workarounds:

1. Write your own custom object that supports multi-awaiting.
2. Use an existing object that supports multi-awaiting (such as `Concurrency::task`).
3. Use a kernel handle and `resume_on_signal`.

Option 3 is probably simplest.

Option 3 worked for my case.

Related