#c #windows-runtime #windows-10 #windows-store #wrl
#c #windows-среда выполнения #windows-10 #windows-store #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. Извините. Для
Cancel
методаopAppLic
нет. Я обновил свой первоначальный пост подробностями.2. @c00000fd В документации MSDN, на которую я ссылался в своем ответе, указано иное: »
IAsyncOperation<TResult>
наследуетсяIAsyncInfo
. Типы, которые реализуютIAsyncOperation<TResult>
, также реализуют элементы интерфейсаIAsyncInfo
:Cancel
метод ,Close
метод,ErrorCode
свойство,Id
property,Status
property » Похоже, что настоящим виновником являетсяRemoveIUnknown*
возвращаемыйComPtr::operator->()
. Я не знаю почему, но попробуйте использоватьopAppLic.Get()->Cancel()
вместо этого, посколькуGet()
не используетRemoveIUnknown
.3. Спасибо. Я вижу документацию. Хотел бы я знать больше об этом материале, чтобы понять, почему
Cancel
метода там нет. Я обновил свой OP дополнительной информацией.4. Эй, есть еще идеи по этому поводу?
5. @c00000fd: Извините, я не могу ответить на этот вопрос. Я не использую WRL.
Ответ №2:
Кто бы ни сталкивался с этим. Кажется, я понял. Реми Лебо был частично прав. Что мне нужно было сделать, так это получить IAsyncInfo
via QueryInterface
как таковой:
ComPtr<IAsyncInfo> pAsyncInfo;
if(SUCCEEDED(opAppLic->QueryInterface(__uuidof(pAsyncInfo), amp;pAsyncInfo)) amp;amp;
pAsyncInfo)
{
if(SUCCEEDED(pAsyncInfo->Cancel()))
{
//Async op was now canceled
//Also note that `onAppLicCompletedCallback` will be called
//with `status` set to `Canceled`
}
}
Комментарии:
1.
ComPtr
предоставляет более простой синтаксис для выполненияQueryInterface()
с помощьюAs()
метода. например.ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo; opAppLic.As(amp;pAsyncInfo)
. Для получения дополнительной информации см. — github.com/Microsoft/DirectXTK/wiki /…2. Добавление к моему предыдущему комментарию —
ComPtr<ABI::Windows::Foundation::IAsyncInfo> pAsyncInfo; opAppLic.As(amp;pAsyncInfo)
эквивалентноopAppLic->QueryInterface(__uuidof(pAsyncInfo), amp;pAsyncInfo))