问题
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