[Windows翻译]取消一个Windows Runtime异步操作,第4部分:C++/CX与PPL,coroutine风格的原始IAsyncAction和..

205 阅读1分钟

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

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

发布时间:2020年7月6日

取消一个Windows Runtime异步操作,第4部分:C++/CX与PPL,coroutine风格的原始IAsyncAction和IAsyncOperation

上一次,我们看了C++/CX中的任务取消是如何用PPL和co_await与任务进行投影的。但是PPL也支持直接在IAsyncAction^和IAsyncOperation^对象上进行等待。我们来试一试。

auto picker = ref new FileOpenPicker();
picker->FileTypeFilter.Append(L".txt");

auto pickerOp = picker->PickSingleFileAsync();
cancellation_token_source cts;
call<bool> do_cancel([pickerOp](bool) { pickerOp.Cancel(); });
timer<bool> delayed_cancel(3000U, false, &do_cancel);
delayed_cancel.start();

StorageFile^ file;
try {
    file = co_await pickerOp;
} catch (OperationCanceledException^) {
    file = nullptr;
}

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

请注意,直接在一个 IAsyncAction^ 和 IAsyncOperation^ 对象上等待与在一个任务上等待是不同的异常。

你可以在 pplawait.h 中的 IAsyncInfo^ awaiter ind 的 await_resume 中看到这一点。

template <typename _TaskTy, typename _HandlerTy>
struct _IAsync_awaiter {
    ...

    auto await_resume() {
        _VerifyStateForResultsCall(_Task->Status);
        return _Task->GetResults();
    }
};

void _VerifyStateForResultsCall(
    Windows::Foundation::AsyncStatus _Status)
{
    if (_Status == AsyncStatus::Canceled) {
        throw ::Platform::Exception::CreateException(E_ABORT);
    }
}

PPL框架检查异步操作的状态是否为Canceled,如果是,则抛出E_ABORT,在C++/CX中表示为OperationCanceledException。

到目前为止,所有的Canceled异常都是由框架产生的。这种情况很快就会改变。下一次,我们将看看C++/WinRT。


通过www.DeepL.com/Translator (免费版)翻译