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_, and sometimes an hresult_. 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_ 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.
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
C++/WinRT doesn’t use .NET at all – it’s a C++ library – so changes to .NET shouldn’t affect it.
Okay, I mixed it up.
I saw C++/WinRT is for writing UWP and always thought it is a .NET technology.