Windows Runtime — Как отменить функцию асинхронного обратного вызова в C ++ / WRL?

Я пишу Windows 10 Store / WinRT код, используя C ++ / WRL который я новичок. И мне любопытно узнать, как отменить давно ожидающую асинхронную операцию?

Лучший способ проиллюстрировать это на следующем примере:

#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?
}

РЕДАКТИРОВАТЬ: Когда я пытался добавить opAppLic->Cancel() как было предложено в ответе ниже, это дало мне следующую ошибку компилятора:

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>          ]

Нужно ли мне QueryInterface тот IAsyncInfo вместо этого или как?

EDIT2: Это то, что я получаю за тип opAppLic переменная:

введите описание изображения здесь

И нет, это не имеет Cancel метод:

введите описание изображения здесь

1

Решение

IAsyncOperation<TResult> имеет Cancel() метод, унаследованный от IAsyncInfo.

Вы не можете отменить Completed Сам обработчик. Он запускается после завершения асинхронной операции. Вы должны отменить операцию, а затем Completed Обработчик сообщает об окончательном статусе операции.

#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();
1

Другие решения

Кто бы ни столкнулся с этим. Я думаю, что понял. Реми Лебо было частично правильно. Что мне нужно было сделать, это получить IAsyncInfo с помощью QueryInterface в качестве таких:

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`
}
}
1

По вопросам рекламы [email protected]