协程中断示例
标志位
#include <QApplication>
#include <QPushButton>
#include <QDebug>
#include <QThread>
#include <coroutine>
#include <atomic>
#include <iostream>
struct HelloCoroutine {
struct HelloPromise {
HelloCoroutine get_return_object() {
return std::coroutine_handle<HelloPromise>::from_promise(*this);
}
std::suspend_never initial_suspend() {
qDebug() << "==============initial_suspend==============";
return {};
}
std::suspend_never final_suspend() noexcept {
qDebug() << "==============final_suspend==============";
return {};
}
void unhandled_exception() {}
void return_void() {
qDebug() << "==============return_value==============";
}
};
using promise_type = HelloPromise;
HelloCoroutine(std::coroutine_handle<HelloPromise> h) : handle(h) {}
~HelloCoroutine() {
if (handle) {
handle.destroy();
}
}
std::coroutine_handle<HelloPromise> handle;
};
auto add(int a, int b, std::atomic<bool>& cancelFlag) {
struct AddAwaitable {
int a, b;
std::atomic<bool>& cancelFlag;
bool await_ready() const noexcept {
return false;
}
void await_suspend(std::coroutine_handle<> h) const noexcept {
QThread::create([this, h](){
QThread::sleep(1);
if (!cancelFlag.load()) {
h.resume();
} else {
qDebug() << "================cancel==================";
h.resume();
}
})->start();
}
int await_resume() const noexcept {
return a + b;
}
};
return AddAwaitable{a, b, cancelFlag};
}
HelloCoroutine hello(std::atomic<bool>& cancelFlag) {
for (int i = 1; i <= 10; i++) {
int res = co_await add(i, 0, cancelFlag);
qDebug() << "res = " << res;
}
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton button("Cancel Coroutine", nullptr);
button.resize(200, 100);
button.show();
std::atomic<bool> cancelFlag(false);
HelloCoroutine coro = hello(cancelFlag);
QObject::connect(&button, &QPushButton::clicked, [&cancelFlag](){
cancelFlag.store(true);
});
QThread::create([&](){
QThread::sleep(3);
cancelFlag.store(true);
})->start();
return QApplication::exec();
}
异常
#include <QApplication>
#include <QPushButton>
#include <QDebug>
#include <QThread>
#include <coroutine>
#include <atomic>
#include <iostream>
#include <iostream>
#include <coroutine>
#include <stdexcept>
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
std::suspend_never initial_suspend() {
qDebug() << "=============initial_suspend=======================";
return {};
}
std::suspend_never final_suspend() noexcept {
qDebug() << "=============final_suspend=======================";
return {};
}
void unhandled_exception() {
qDebug() << "================unhandled_exception===============";
}
void return_void() {}
};
};
auto add(int a, int b) {
struct awaitable {
int a, b, result;
bool await_ready() {
return false;
}
void await_suspend(std::coroutine_handle<> h) {
QThread::create([=](){
QThread::sleep(1);
result = a + b;
h.resume();
})->start();
}
int await_resume() {
return result;
}
};
return awaitable{a, b};
}
Task my_coroutine() {
for (int i = 1; i <= 10; i++) {
int res = co_await add(i, 0);
qDebug() << "res = " << res;
if (i == 5) {
throw std::runtime_error("An error occurred in coroutine");
}
}
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton button("Cancel Coroutine", nullptr);
button.resize(200, 100);
button.show();
my_coroutine();
return QApplication::exec();
}