July 3rd, 2020

Cancelling a Windows Runtime asynchronous operation, part 3: C++/CX with PPL, coroutine style

Last time, we looked at how task cancellation is projected in C++/CX with PPL and explicit continuations. But how about C++/CX with PPL and coroutines?

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

cancellation_token_source cts;
call<bool> do_cancel([cts](bool) { cts.cancel(); });
timer<bool> delayed_cancel(3000U, false, &do_cancel);
delayed_cancel.start();

StorageFile^ file;
try {
    file = co_await create_task(picker->PickSingleFileAsync(), cts.get_token());
} catch (task_canceled const&) {
    file = nullptr;
}

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

Notice that coroutines save us a lot of the hassle of setting up the call and timer because the objects live in the coroutine frame, which continues to exist until the coroutine completes.

Again, the task throws a task_canceled upon cancellation. This time, it’s because of the await_resume for the task awaiter, which you can find in pplawait.h:

template <typename _Ty>
struct _Ppltask_awaiter {
    ...

    decltype(auto) await_resume() {
        return _Task.get();
    }
};

But wait, the PPL library also supports awaiting on raw IAsyncAction^ and IAsyncOperation^ objects. Next time, we’ll look at what happens in that case.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.

Feedback