How to cancel asynchronous callback function in C++/WRL?

旧时模样 提交于 2019-12-08 06:08:59

问题


I'm writing Windows 10 Store / WinRT code using C++/WRL which I'm new to. And I'm curious to know how do I cancel long-pending asynchronous operation?

The best way to illustrate it is with this example:

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

auto onAppLicCompletedCallback = Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncOperationCompletedHandler<StoreAppLicense*>, FtmBase>>(
    [](IAsyncOperation<StoreAppLicense*>* operation, AsyncStatus status)
{
    //Asynchronous operation is done
    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'
    //but how do I do it?
}

EDIT: When I tried to add opAppLic->Cancel() as was suggested in the answer below, it gave me the following compiler error:

1>file-name.cpp(597): error C2039: 'Cancel' : is not a member of 'Microsoft::WRL::Details::RemoveIUnknownBase<T>'
1>          with
1>          [
1>              T=ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Services::Store::StoreAppLicense*>
1>          ]

Do I need to QueryInterface that IAsyncInfo instead, or what?

EDIT2: This is what I'm getting for the type of opAppLic variable:

And no, it doesn't have the Cancel method:


回答1:


IAsyncOperation<TResult> has a Cancel() method inherited from IAsyncInfo.

You cannot cancel the Completed handler itself. It is fired when the async operation is finished. You have to cancel the operation instead, and then the Completed handler reports the final status of the operation.

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

auto onAppLicCompletedCallback = Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncOperationCompletedHandler<StoreAppLicense*>, FtmBase>>(
    [](IAsyncOperation<StoreAppLicense*>* operation, AsyncStatus status)
{
    //Asynchronous operation is done
    if (status == completed)
    {
        // use results from operation->GetResults() as needed...
    }
    return S_OK;
});

ComPtr<IAsyncOperation<StoreAppLicense*>> opAppLic;
// Begin asynchronous operation that assigns opAppLic...

opAppLic->put_Completed(onAppLicCompletedCallback.Get());

//Keep going ...

//Say, at some point here I need to cancel the operation...
opAppLic->Cancel();



回答2:


Whoever also runs into this. I think I got it. Remy Lebeau was partially correct. What I needed to do was to obtain IAsyncInfo via QueryInterface as such:

ComPtr<IAsyncInfo> pAsyncInfo;
if(SUCCEEDED(opAppLic->QueryInterface(__uuidof(pAsyncInfo), &pAsyncInfo)) &&
    pAsyncInfo)
{
    if(SUCCEEDED(pAsyncInfo->Cancel()))
    {
        //Async op was now canceled
        //Also note that `onAppLicCompletedCallback` will be called
        //with `status` set to `Canceled`
    }
}


来源:https://stackoverflow.com/questions/40201439/how-to-cancel-asynchronous-callback-function-in-c-wrl

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