in include/wil/winrt.h [1358:1401]
HRESULT RunWhenComplete(_In_ TIOperation operation, TFunction&& func) WI_NOEXCEPT
{
using namespace Microsoft::WRL;
using namespace ABI::Windows::Foundation::Internal;
typedef wistd::remove_pointer_t<decltype(GetAsyncDelegateType(operation))> TIDelegate;
auto callback = Callback<Implements<RuntimeClassFlags<ClassicCom>, TIDelegate, TBaseAgility>>(
[func = wistd::forward<TFunction>(func)](TIOperation operation, ABI::Windows::Foundation::AsyncStatus status) mutable -> HRESULT
{
typename details::MapToSmartType<typename GetAbiType<typename wistd::remove_pointer<TIOperation>::type::TResult_complex>::type>::type result;
HRESULT hr = S_OK;
// avoid a potentially costly marshaled QI / call if we completed successfully
if (status == ABI::Windows::Foundation::AsyncStatus::Completed)
{
hr = operation->GetResults(result.GetAddressOf());
}
else
{
// QI to the IAsyncInfo interface. While all operations implement this, it is
// possible that the stub has disconnected, causing the QI to fail.
ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
hr = operation->QueryInterface(IID_PPV_ARGS(&asyncInfo));
if (SUCCEEDED(hr))
{
// Save the error code result in a temporary variable to allow us
// to also retrieve the result of the COM call. If the stub has
// disconnected, this call may fail.
HRESULT errorCode = E_UNEXPECTED;
hr = asyncInfo->get_ErrorCode(&errorCode);
if (SUCCEEDED(hr))
{
// Return the operations error code to the caller.
hr = errorCode;
}
}
}
return CallAndHandleErrors(func, hr, result.Get());
});
RETURN_IF_NULL_ALLOC(callback);
return operation->put_Completed(callback.Get());
}