HRESULT RunWhenComplete()

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());
    }