How to properly wait for asynchronous WinRT callback functions to stop?

一曲冷凌霜 提交于 2020-01-25 21:52:08

问题


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?

来源:https://stackoverflow.com/questions/40354594/how-to-properly-wait-for-asynchronous-winrt-callback-functions-to-stop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!