Cancelling a Windows Runtime asynchronous operation, part 5: C++/WinRT

Raymond Chen

Last time, we looked at how task cancellation is projected in C++/CX with PPL and co_await with IAsyncAction^ and IAsyncOperation^ objects. Our next investigation is C++/WinRT.

FileOpenPicker openPicker;
openPicker.FileTypeFilter().Append(L".txt");
auto pickerOp = openPicker.PickSingleFileAsync();
([](auto op) -> fire_and_forget { co_await resume_after(3s); op.Cancel(); })(pickerOp);

StorageFile file{ nullptr };
try
{
    file = co_await pickerOp;
}
catch (hresult_canceled const&)
{
    file = nullptr;
}
catch (hresult_illegal_method_call const&)
{
    file = nullptr;
}

if (file != nullptr)
{
    DoSomething(file);
}

Canceling the operation after a delay is slightly tricky because we need to pass the pickerOp as a parameter to a captureless lambda, rather than capturing it into the lambda. We discussed the reason for this some time ago.

The exception that comes out of awaiting for a canceled task is sometimes an hresult_canceled, and sometimes an hresult_illegal_method_call. The reason is that C++/WinRT defers to the IAsyncAction/IAsyncOperation to decide what exception to raise.¹

In other words, C++/WinRT just takes the ABI result and propagates it. It doesn’t try to impose its will upon the result.

You can see this in the await_resume for asynchronous operations:

template <typename Async>
struct await_adapter
{
    ...

    auto await_resume() const
    {
        return async.GetResults();
    }
};

Whatever exception comes out of Get­Results() is the exception that comes out of the co_await.

Next time, we’ll look at what happens if the IAsyncAction or IAsyncOperation was implemented by the C++/WinRT library itself.

Bonus chatter: This entire article is already obsolete. We’ll learn more about it when this series wraps up.

¹ Therefore, in principle, it could be utterly anything since it’s up to the ABI to generate the HRESULT that turns into an exception at the projection.

3 comments

Discussion is closed. Login to edit/delete existing comments.

  • cheong00 0

    While we’re on the topic with WinRT, I wonder if “removal of built-in WinRT support of .NET 5” will have impact on C++/WinRT or there will be another project to support it.

    https://github.com/dotnet/runtime/issues/37672

    • Max Strini 0

      C++/WinRT doesn’t use .NET at all – it’s a C++ library – so changes to .NET shouldn’t affect it.

      • cheong00 0

        Okay, I mixed it up.

        I saw C++/WinRT is for writing UWP and always thought it is a .NET technology.

Feedback usabilla icon