Last time, we saw that if a C++/WinRT asynchronous operation is cancelled, the result is an hresult_
. Today, we’ll look at another implementation library for asynchronous operations: The Windows Runtime Template Library (WRL).
WRL is a bit out of fashion nowadays, but back in its heyday, it was the stuff everybody used for creating Windows Runtime objects and asynchronous operations.
class AsyncBase< ... > : ...
{
inline HRESULT CheckValidStateForResultsCall()
{
Details::AsyncStatusInternal current = Details::_Undefined;
CurrentStatus(¤t);
if (current == Details::_Error)
{
...
}
if (resultType == SingleResult)
{
if (current != Details::_Completed)
{
::RoOriginateError(E_ILLEGAL_METHOD_CALL, nullptr);
return E_ILLEGAL_METHOD_CALL;
}
}
...
}
};
The CheckÂValidÂStateÂForÂResultsÂCall
method does what is says: It validates that the operation is in a correct state for a call to GetÂResults()
. In the case where the operation has been canceled, we fail the first test (which propagates any explicit error code), but make it into the second part. This is a single-result operation¹ and a cancelled operation is not complete, so it returns E_
, which propagates back into C++/WinRT as hresult_
.
And that solves the mystery of why some cancelled operations throw an hresult_
exception. It took us a week to get here, but we finally made it. The propagation of cancellation is a delicate dance between the the operation and the awaiter, and it’s easy to stumble.
¹ Nearly all Windows Runtime asynchronous operations are single-result. There’s another rarely-seen variant called the multiple-result asynchronous operation, which lets you call GetÂResults
before the operation has completed, and it gives you the result-so-far. I am not aware of any operations that do this, but the code supports.
0 comments