2016-10-23 77 views
1

我正在使用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>   ] 

我需要QueryInterfaceIAsyncInfo取而代之,還是什麼?

EDIT2:這就是我得到了opAppLic變量的類型:

enter image description here

不,它不具備Cancel方法:

enter image description here

回答

1

IAsyncOperation<TResult>有一個Cancel()繼承自的方法。

您不能取消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(); 
+0

對不起。 opAppLic沒有'Cancel'方法。我更新了原始文章的詳細信息。 – c00000fd

+0

@ c00000fd我在我的答案中鏈接到的MSDN文檔聲明:「*'IAsyncOperation '繼承'IAsyncInfo'。實現'IAsyncOperation '的類型也實現'IAsyncInfo'的接口成員:**'Cancel'方法* *,'Close'方法,'ErrorCode'屬性,'Id'屬性,'Status'屬性*「看起來真正的罪魁禍首是由'ComPtr :: operator - >()'返回的'RemoveIUnknown *'。我不知道爲什麼,但是嘗試使用'opAppLic.Get() - > Cancel()',因爲'Get()'不使用'RemoveIUnknown'。 –

+0

謝謝。我看到了文檔。我希望我知道更多關於這個東西的信息,知道爲什麼'Cancel'方法不存在。我用更多的信息更新了我的OP。 – c00000fd

1

誰也碰到過這個。我想我明白了。 Remy Lebeau部分正確。我需要做的是通過QueryInterface獲得IAsyncInfo原樣:

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` 
    } 
} 
+0

'ComPtr'爲'As()'方法提供了一個更簡單的語法來執行'QueryInterface()'。例如。 'ComPtr pAsyncInfo; opAppLic.As(&pAsyncInfo)'。 欲瞭解更多信息,請參閱 - https://github.com/Microsoft/DirectXTK/wiki/ComPtr#obtaining-new-interfaces –

+0

_Adding to my previous comment_ - 'ComPtr pAsyncInfo; (&pAsyncInfo)''相當於'opAppLic-> QueryInterface(__ uuidof(pAsyncInfo),&pAsyncInfo))' –