[Windows翻译]取消Windows Runtime异步操作,第7部分:WRL生成的异步操作。

364 阅读1分钟

原文地址:devblogs.microsoft.com/oldnewthing…

原文作者:devblogs.microsoft.com/oldnewthing…

发布时间:2020年7月9日

上一次,我们看到,如果一个C++/WinRT异步操作被取消,结果是一个hresult_canceled。今天,我们就来看看另一个异步操作的实现库。Windows Runtime模板库(WRL)。

WRL现在已经有点过时了,但在它的全盛时期,它是大家用来创建Windows Runtime对象和异步操作的东西。

class AsyncBase< ... > : ...
{
    inline HRESULT CheckValidStateForResultsCall()
    {
        Details::AsyncStatusInternal current = Details::_Undefined;
        CurrentStatus(&current);

        if (current == Details::_Error)
        {
            ...
        }

        if (resultType == SingleResult)
        {
            if (current != Details::_Completed)
            {
                ::RoOriginateError(E_ILLEGAL_METHOD_CALL, nullptr);
                return E_ILLEGAL_METHOD_CALL;
            }
        }
        ...
    }
};

CheckValidStateForResultsCall方法的作用是:验证操作是否处于正确的状态,以便调用GetResults()。在操作已被取消的情况下,我们会失败第一项测试(会传播任何显式错误代码),但会使其进入第二部分。这是一个单结果操作¹,被取消的操作是不完整的,所以它返回E_ILLEGAL_METHOD_CALL,它以hresult_illegal_method_call的形式传播回C++/WinRT中。

这就解决了为什么一些被取消的操作会抛出一个hresult_illegal_method_call异常的谜团。我们花了一个星期的时间,但我们终于做到了。取消操作的传播是操作和等待者之间的微妙舞蹈,很容易被绊倒。

¹几乎所有的Windows Runtime异步操作都是单结果的。还有一种很少见的变体叫做多结果异步操作,它让你在操作完成之前就调用GetResults,它给你结果-so-far。我不知道有什么操作可以这样做,但代码支持。


www.deepl.com 翻译