原文地址: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 (免费版)翻译