Непонятно, как использовать winrt :: get_cancellation_token для IAsyncAction - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь написать фоновый поток на основе сопрограмм в C ++ / WinRT, который зацикливается на состоянии токена отмены, потому что мне нужно предпринять некоторые действия по очистке отмены.

Я пытаюсь следовать документации по MSDN (https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/concurrency#canceling-an-asychronous-operation-and-cancellation-callbacks), но адаптация примера кода не компилируется, а тип cancellation_token_t не вызывается.

void BackgroundThreadManager::Start()
{
    this->m_Thread = this->RunAsync();
}

void BackgroundThreadManager::Stop()
{
    if (this->m_Thread)
    {
        m_Thread.Cancel();
        m_Thread = nullptr;
    }
}

IAsyncAction BackgroundThreadManager::RunAsync()
{
    winrt::resume_background();
    auto token{ winrt::get_cancellation_token() };
    while (!token())
    {
        co_await this->DoSomethingAsync();
    }
    co_await this->DoSomeCleanupAsync();
}

К сожалению, это не скомпилируется с ошибкой «C2064: term не оценивает функцию, принимающую 0 аргументов» со ссылкой на строку while (! Token ()).

Код согласен с этим, так как определение (в base.h) get_cancellation_token_t равно

struct get_cancellation_token_t {};

Я полагаю, что я делаю что-то не так, или документация MSDN устарела. Есть какие-нибудь подсказки? Спасибо!

1 Ответ

0 голосов
/ 14 января 2019

Вы забываете co_await в выражении get_cancellation_token(). co_await предоставляет хук, к которому библиотека должна обратиться и получить экземпляр IAsyncAction, который может быть отменен. Кстати, вы также забыли co_await выражение resume_background().

Также обратите внимание, что сопрограммы также автоматически отменяются в точках приостановки (co_await), поэтому может быть лучше использовать обратный вызов отмены, чтобы убедиться, что логика отмены не пропущена.

...