我正在编写代码以WinRT
使用 C++ WRL(即不使用 C++/CX 或 C++/CLI)在 Windows 10 上使用 API。我正在使用Package 类中的GetAppListEntriesAsync()来获取安装在系统上的 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())
Where保存对异步调用cb
的回调函数的引用。GetAppListEntriesAsync()
(见更新2)
有几个这样的异步操作被调用。我想运行一段代码,该代码只有在所有此类异步回调完成后才能运行。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_MULTITHREADED
但RoInitialize()
失败,但是 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