如何等待IAsyncOperation完成使用C ++ WRL?

时间:2017-08-04 19:18:49

标签: com windows-runtime atl winrt-async wrl

我正在编写代码以使用C ++ WRL在Windows 10上使用WinRT API(即不使用C ++ / CX或C ++ / CLI)。我使用GetAppListEntriesAsync()中的Package class来获取系统上安装的UWP应用程序的名称。 GetAppListEntriesAsync()异步调用回调方法。我想等到所有这些异步方法都完成了。与C++/CX WRL不同,没有任何await关键字可以等待异步任务。

详情

以下代码用于获取列表。

ComPtr<ABI::Windows::Foundation::__FIAsyncOperation_1___FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry_t> operation;
package3->GetAppListEntriesAsync(&operation);

package3是指向ABI::Windows::ApplicationModel::IPackage3类型的指针: -

ComPtr<ABI::Windows::ApplicationModel::IPackage3> package3;

我按如下方式调用异步操作。

operation->put_Completed(cb.Get())

cb保持对GetAppListEntriesAsync()异步调用的回调函数的引用。 (见update2)

有几个这样的异步操作被调用。我想运行一段代码,只有在所有这些异步回调完成后才能运行。 C++/CX具有await关键字,用于等待异步任务。 我应该如何使用WRL C++做同样的事情? 我尝试使用WaitForSingleObject(),但它似乎无法运作。

一种非常粗野的方法是在while循环中继续检查每个异步操作的状态。

ComPtr<ABI::Windows::Foundation::IAsyncInfo> ai;
operation.As(&ai);
while (true) 
{
ai->get_Status(&status);
if (status == Started) 
{
continue;
}
else
{
break;
}
}

我不确定这是否有效,或者是否会导致性能下降。我的代码的COM公寓类型是APTTYPE_STA(请注意这条信息是否与问题相关;我想设置为RO_INIT_MULTITHREADEDRoInitialize()失败,但WRL代码似乎工作正常。)

更新2:

以下是cb(回调)的实现方式。

    auto cb = wrl::Callback<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry_t *>>(
                    [](ABI::Windows::Foundation::__FIAsyncOperation_1___FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry_t * ppp, AsyncStatus status) -> HRESULT 
{
    <do something in callback>;
    SetEvent(threadCompleted.Get());
}

尝试实施IAgileObject

要制作我的回调工具IAgileObject,我必须使用Implements<> WRL模板类。所以回调类似于auto cb = Callback<Implements<IAgileObject,...>>,但问题是IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry_t *>并非来自IInspectable,因此使用的是: -

Callback<Implements<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::__FIVectorView_1_Windows__CApplicationModel__CCore__CAppListEntry_t *>,IAgileObject>>出现以下错误(Visual Studio 2017)。

Error C2338 'I' has to derive from 'IWeakReference', 'IWeakReferenceSource' or 'IInspectable' AsyncTask c:\sw\tools\sdk\winsdk\win10\include\winrt\wrl\implements.h 413

0 个答案:

没有答案