How to properly wait for asynchronous WinRT callba

2019-09-13 09:21发布

I asked a similar question before but the answer there did not satisfy my requirement. Let me explain.

I call the following code from a DLL to perform a WinRT operation on Windows 10 from a Windows Store app. The code uses WRL:

#include <Windows.Services.Store.h>
#include <wrl.h>

auto onAppLicCompletedCallback = Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncOperationCompletedHandler<StoreAppLicense*>, FtmBase>>(
    [](IAsyncOperation<StoreAppLicense*>* operation, AsyncStatus status)
{
    if(status == AsyncStatus::Completed)
    {
       //Do actions of the async operation
       ...
    }

    return S_OK;
});

//'opAppLic' is defined as:
// ComPtr<IAsyncOperation<StoreAppLicense*>> opAppLic;
// ...

//Begin asynchronous operation
HRESULT hr = opAppLic->put_Completed(onAppLicCompletedCallback.Get());
if (SUCCEEDED(hr))
{
    //Keep going ...

    //Say, at some point here I need to cancel 'onAppLicCompletedCallback'
    //after a user clicks Cancel button via a UI, so I do this:
    ComPtr<IAsyncInfo> pAsyncInfo;
    if(SUCCEEDED(opAppLic->QueryInterface(__uuidof(pAsyncInfo), &pAsyncInfo)) &&
        pAsyncInfo)
    {
        pAsyncInfo->Cancel();
    }
}

//And now unload DLL

but when I call the IAsyncInfo::Cancel() method and unload the DLL immediately after, that causes a race condition and sometimes crashes the app.

Purely experimentally I noticed that after a call to IAsyncInfo::Cancel() the framework calls my onAppLicCompletedCallback method with status set to AsyncStatus::Canceled. But this call also happens asynchronously long after IAsyncInfo::Cancel() method returns.

So I was wondering, is there a way to wait for all WinRT asynchronous callbacks to finish running before I can proceed with unloading my DLL?

0条回答
登录 后发表回答