QFuture
Module | Core |
---|---|
Include |
|
CMake |
|
QMake |
|
QFuture
, which represents an asynchronously executed call, doesn't have any
operation on its own that could be awaited asynchronously, this is usually done through a helper
class called QFutureWatcher
. To simplify the API, QCoro allows to directly
co_await
completion of the running QFuture
or use of a wrapper class QCoroFuture
. To wrap
a QFuture
into a QCoroFuture
, use qCoro()
:
template<typename T>
QCoroFuture qCoro(const QFuture<T> &future);
It's possible to directly co_await
a completion of a QFuture
and obtain a result:
const QString result = co_await QtConcurrent::run(...);
This is a convenient alternative to using co_await qCoro(future).result()
.
result()
Asynchronously waits for the QFuture<T>
to finish and returns the result of the future. If the future
result type is void
, then returns nothing. If the asynchronous operation has thrown an exception, it
will be rethrown here.
Example:
QFuture<QString> future = QtConcurrent::run(...);
const QString result = co_await qCoro(future).result();
This is equivalent to using QFutureWatcher
and then retrieving the result using
QFuture::result()
:
QFuture<QString> future = QtConcurrent::run(...);
auto watcher = new QFutureWatcher<QString>();
connect(watcher, &QFutureWatcherBase::finished,
this, [watcher]() {
watcher->deleteLater();
auto result = watcher.result();
...
});
watcher->addFuture(future);
takeResult()
Asynchronously waits for the QFuture<T>
to finish and returns the result of the future by taking
(moving) it from the future object. If the asynchronous operation has thrown an exception, it will
be rethrown here.
This is useful when dealing with move-only types (like std::unique_ptr
) or when you simply want to
move the result instead of copying it out from the future.
Example:
QFuture<std::unique_ptr<Result>> future = QtConcurrent::run(...);
auto result = co_await qCoro(future).takeResult();
This is equivalent to using QFutureWatcher
and then retrieving the result using
QFuture::takeResult()
:
QFuture<std::unique_ptr<Result>> future = QtConcurrent::run(...);
auto watcher = new QFutureWatcher<std::unique_ptr<Result>>();
connect(watcher, &QFutureWatcherBase::finished,
this, [watcher]() {
watcher->deleteLater();
auto result = watcher.future().takeResult();
...
});
watcher->addFuture(future);
See documentation for QFuture::takeResult()
for limitations regarding
moving the result out from QFuture
.
This method is only available in Qt 6.
waitForFinished()
This is equivalent to using the result()
method.
Example
#include <QCoroFuture>
QCoro::Task<> runTask() {
// Starts a concurrent task and co_awaits on the returned QFuture. While the task is
// running, the coroutine is suspended.
const QString value = co_await QtConcurrent::run([]() {
QString result;
...
// do some long-running computation
...
return result;
});
// When the future has finished, the coroutine is resumed and the result of the
// QFuture is returned and stored in `value`.
// ... now do something with the value
}