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.