我正在编写代码以使用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_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