Класс QFuture
template <typename T> class QFutureКласс QFuture представляет результат асинхронного вычисления. Подробнее...
| Заголовок: | #include <QFuture> |
| CMake: | find_package(Qt6 COMPONENTS Core REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
Примечание: Все функции в этом классе являются потокобезопасными за следующими исключениями:
Открытые типы
| class | const_iterator |
| ConstIterator |
Открытые функции
| QFuture(const QFuture<T> &other) | |
| QFuture() | |
| QFuture<T> & | operator=(const QFuture<T> &other) |
| ~QFuture() | |
| QFuture::const_iterator | begin() const |
| void | cancel() |
| QFuture::const_iterator | constBegin() const |
| QFuture::const_iterator | constEnd() const |
| QFuture::const_iterator | end() const |
| bool | isCanceled() const |
| bool | isFinished() const |
| bool | isResultReadyAt(int index) const |
| bool | isRunning() const |
| bool | isStarted() const |
| bool | isSuspended() const |
| bool | isSuspending() const |
| bool | isValid() const |
| QFuture<T> | onCanceled(Function &&handler) |
| QFuture<T> | onCanceled(QObject *context, Function &&handler) |
| QFuture<T> | onFailed(Function &&handler) |
| QFuture<T> | onFailed(QObject *context, Function &&handler) |
| int | progressMaximum() const |
| int | progressMinimum() const |
| QString | progressText() const |
| int | progressValue() const |
| T | result() const |
| T | resultAt(int index) const |
| int | resultCount() const |
| QList<T> | results() const |
| void | resume() |
| void | setSuspended(bool suspend) |
| void | suspend() |
| T | takeResult() |
| QFuture<ResultType<Function> > | then(Function &&function) |
| QFuture<ResultType<Function> > | then(QtFuture::Launch policy, Function &&function) |
| QFuture<ResultType<Function> > | then(QThreadPool *pool, Function &&function) |
| QFuture<ResultType<Function> > | then(QObject *context, Function &&function) |
| void | toggleSuspended() |
| void | waitForFinished() |
Подробное описание
QFuture позволяет синхронизировать потоки с одним или несколькими результатами, которые будут готовы позже. Результат может быть любого типа, имеющего конструкторы по умолчанию, копирования и, возможно, перемещения. Если результат недоступен во время вызова функций result(), resultAt(), results() и takeResult(), QFuture будет ждать, пока результат не станет доступен. Вы можете использовать функцию isResultReadyAt() для определения готовности результата. Для объектов QFuture, которые возвращают более одного результата, функция resultCount() возвращает количество непрерывных результатов. Это означает, что всегда безопасно итерироваться по результатам от 0 до resultCount(). takeResult() делает future недействительным, и любая последующая попытка доступа к результату или результатам из future приводит к неопределенному поведению. isValid() сообщает, можно ли получить доступ к результатам.
QFuture предоставляет итератор в стиле Java (QFutureIterator) и итератор в стиле STL (QFuture::const_iterator). Использование этих итераторов — еще один способ доступа к результатам в будущем.
Если результат одного асинхронного вычисления необходимо передать другому, QFuture предоставляет удобный способ объединения нескольких последовательных вычислений с помощью then(). onCanceled() можно использовать для добавления обработчика, который будет вызван, если QFuture отменен. Кроме того, onFailed() можно использовать для обработки любых ошибок, возникших в цепочке. Обратите внимание, что QFuture полагается на исключения для обработки ошибок. Если использование исключений невозможно, вы все равно можете указать состояние ошибки QFuture, сделав тип ошибки частью типа QFuture. Например, вы можете использовать std::variant, std::any или аналогичный для хранения результата или ошибки или создать свой собственный тип.
В примере ниже показано, как можно обрабатывать ошибки без использования исключений. Допустим, мы хотим отправить сетевой запрос для получения большого файла из сетевого расположения. Затем мы хотим записать его в файловую систему и вернуть его местоположение в случае успеха. Обе эти операции могут завершиться неудачей с различными ошибками. Поэтому мы используем std::variant для хранения результата или ошибки:
using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>;
enum class IOError { FailedToRead, FailedToWrite };
using IOResult = std::variant<QString, IOError>; И мы объединяем две операции с помощью then():
QFuture<IOResult> future = QtConcurrent::run([url] {
...
return NetworkReply(QNetworkReply::TimeoutError);
}).then([](NetworkReply reply) {
if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply))
return IOResult(IOError::FailedToRead);
auto data = std::get_if<QByteArray>(&reply);
// try to write *data and return IOError::FailedToWrite on failure
...
});
auto result = future.result();
if (auto filePath = std::get_if<QString>(&result)) {
// do something with *filePath
else
// process the error Можно объединять несколько продолжений и обработчиков в любом порядке. Например:
QFuture<int> testFuture = ...;
auto resultFuture = testFuture.then([](int res) {
// Block 1
}).onCanceled([] {
// Block 2
}).onFailed([] {
// Block 3
}).then([] {
// Block 4
}).onFailed([] {
// Block 5
}).onCanceled([] {
// Block 6
}); В зависимости от состояния testFuture (отменено, с исключением или с результатом), будет вызван следующий метод onCanceled(), onFailed() или then(). Таким образом, если testFuture успешно выполнено, будет вызван Block 1. Если и это успешно, вызывается следующий метод then() (Block 4). Если testFuture отменено или завершилось с исключением, соответственно вызываются Block 2 или Block 3. После этого вызывается следующий метод then(), и история повторяется.
Примечание: Если Block 2 вызывается и генерирует исключение, следующий метод onFailed() (Block 3) обработает его. Если порядок методов onFailed() и onCanceled() был бы обратным, состояние исключения распространилось бы на следующие продолжения и, в конечном итоге, было бы перехвачено в Block 5.
В следующем примере первый метод onCanceled() (Block 2) удален:
QFuture<int> testFuture = ...;
auto resultFuture = testFuture.then([](int res) {
// Block 1
}).onFailed([] {
// Block 3
}).then([] {
// Block 4
}).onFailed([] {
// Block 5
}).onCanceled([] {
// Block 6
}); Если testFuture отменяется, его состояние передается следующему методу then(), который также будет отменен. Таким образом, в этом случае будет вызван Block 6.
QFuture также предлагает способы взаимодействия с выполняемым вычислением. Например, вычисление можно отменить с помощью функции cancel(). Для приостановки или возобновления вычисления используйте функцию setSuspended() или одну из удобных функций suspend(), resume() или toggleSuspended(). Имейте в виду, что не все выполняемые асинхронные вычисления можно отменить или приостановить. Например, будущее, возвращаемое функцией QtConcurrent::run(), отменить нельзя; но будущее, возвращаемое функцией QtConcurrent::mappedReduced(), можно.
Информация о прогрессе предоставляется функциями progressValue(), progressMinimum(), progressMaximum() и progressText(). Функция waitForFinished() заставляет вызывающую нить заблокироваться и ждать завершения вычисления, гарантируя, что все результаты доступны.
Состояние вычисления, представленного QFuture, можно запросить, используя функции isCanceled(), isStarted(), isFinished(), isRunning(), isSuspending() или isSuspended().
QFuture<void> специализирована для того, чтобы не содержать никаких функций извлечения результатов. Любой QFuture<T> может быть присвоен или скопирован в QFuture<void> также. Это полезно, если требуется только информация о состоянии или прогрессе, а не фактические данные результата.
Для взаимодействия с выполняемыми задачами с помощью сигналов и слотов используйте QFutureWatcher.
Вы также можете использовать QtFuture::connect для подключения сигналов к объекту QFuture, который будет разрешен при отправке сигнала. Это позволяет работать с сигналами, как с объектами QFuture. Например, если вы объедините его с then(), вы можете прикрепить несколько продолжений к сигналу, которые будут вызваны в той же нити или в новой нити.
Готовый объект QFuture со значением или объект QFuture, содержащий исключение, можно создать, используя удобные функции QtFuture::makeReadyFuture и QtFuture::makeExceptionalFuture.
Примечание: Для запуска вычисления и сохранения результатов в QFuture используйте QPromise или один из API в рамках Qt Concurrent.
См. также QPromise, QtFuture::connect(), QtFuture::makeReadyFuture(), QtFuture::makeExceptionalFuture(), QFutureWatcher и Qt Concurrent.
Документация типов членов
QFuture::ConstIterator
Синоним Qt-стиля для QFuture::const_iterator.
Документация функций-членов
QFuture::QFuture(const QFuture<T> &other)
Создает копию other.
См. также operator=().
QFuture::QFuture()
Создает пустое, отменённое будущее.
QFuture<T> &QFuture::operator=(const QFuture<T> &other)
Присваивает other этому будущему и возвращает ссылку на это будущее.
QFuture::~QFuture()
Уничтожает будущее.
Обратите внимание, что это не ожидает и не отменяет асинхронное вычисление. Используйте waitForFinished() или QFutureSynchronizer, когда необходимо убедиться, что вычисление завершено перед уничтожением будущего.
template <typename U, typename> QFuture::const_iterator QFuture::begin() const
Возвращает постоянный итератор STL-стиля, указывающий на первый результат в будущем.
См. также constBegin() и end().
void QFuture::cancel()
Отменяет асинхронное вычисление, представленное этим будущим. Обратите внимание, что отмена асинхронна. Используйте waitForFinished() после вызова cancel(), если вам нужна синхронная отмена.
Результаты, которые в настоящее время доступны, могут быть по-прежнему доступны в отменённом будущем, но новые результаты не будут доступны после вызова этой функции. Любой объект QFutureWatcher, который наблюдает за этим будущим, не будет отправлять сигналы о прогрессе и готовности результата по отменённому будущему.
Обратите внимание, что не все выполняемые асинхронные вычисления могут быть отменены. Например, будущее, возвращаемое функцией QtConcurrent::run(), отменить нельзя; но будущее, возвращаемое функцией QtConcurrent::mappedReduced(), можно.
template <typename U, typename> QFuture::const_iterator QFuture::constBegin() const
Возвращает постоянный итератор STL-стиля, указывающий на первый результат в будущем.
См. также begin() и constEnd().
template <typename U, typename> QFuture::const_iterator QFuture::constEnd() const
Возвращает постоянный итератор STL-стиля, указывающий на воображаемый результат после последнего результата в будущем.
См. также constBegin() и end().
template <typename U, typename> QFuture::const_iterator QFuture::end() const
Возвращает постоянный итератор STL-стиля, указывающий на воображаемый результат после последнего результата в будущем.
См. также begin() и constEnd().
bool QFuture::isCanceled() const
Возвращает true если асинхронное вычисление было отменено с помощью функции cancel(); в противном случае возвращает false.
Обратите внимание, что вычисление может все еще выполняться, даже если эта функция возвращает true. См. cancel() для получения дополнительной информации.
bool QFuture::isFinished() const
Возвращает true если асинхронное вычисление, представленное этим будущим, завершено; в противном случае возвращает false.
template <typename U, typename> bool QFuture::isResultReadyAt(int index) const
Возвращает true если результат в index немедленно доступен; в противном случае возвращает false.
Примечание: Вызов isResultReadyAt() приводит к неопределенному поведению, если isValid() возвращает false для этого QFuture.
См. также resultAt(), resultCount() и takeResult().
bool QFuture::isRunning() const
Возвращает true если асинхронное вычисление, представленное этим будущим, в настоящее время выполняется; в противном случае возвращает false.
bool QFuture::isStarted() const
Возвращает true если асинхронное вычисление, представленное этим будущим, было начато; в противном случае возвращает false.
[since 6.0] bool QFuture::isSuspended() const
Возвращает true если была запрошена приостановка асинхронного вычисления и она в действии, что означает, что больше результатов или изменений прогресса ожидаться не должно.
Эта функция была добавлена в Qt 6.0.
См. также setSuspended(), toggleSuspended() и isSuspending().
[since 6.0] bool QFuture::isSuspending() const
Возвращает true если асинхронное вычисление приостановлено с помощью функции suspend(), но работа еще не приостановлена, и вычисление все еще выполняется. В противном случае возвращает false.
Чтобы проверить, действительно ли приостановка активна, используйте isSuspended() вместо этого.
Эта функция была добавлена в Qt 6.0.
См. также setSuspended(), toggleSuspended() и isSuspended().
[since 6.0] bool QFuture::isValid() const
Возвращает true, если к этому объекту QFuture можно получить доступ или извлечь результат или результаты. Возвращает false после того, как результат был извлечен из будущего.
Эта функция была добавлена в Qt 6.0.
См. также takeResult(), result(), results() и resultAt().
[since 6.0] template <typename Function, typename> QFuture<T> QFuture::onCanceled(Function &&handler)
Прикрепляет обработчик отмены handler к этому будущему. Возвращаемое будущее ведет себя точно так же, как и это будущее (имеет то же состояние и результат), если только это будущее не отменено. handler — это вызываемый объект, который не принимает аргументы и возвращает значение типа, упакованного в этом будущем. После отмены возвращаемое будущее упаковывает значение, возвращенное handler.
Если обработчик прикреплен до отмены, handler будет вызван в том же потоке, который сообщает о завершении будущего после отмены. Если обработчик прикреплен после того, как это будущее уже было отменено, он будет вызван немедленно в потоке, в котором выполняется onCanceled(). Поэтому обработчик не всегда может делать предположения о том, в каком потоке он будет выполняться. Используйте перегрузку, принимающую объект контекста, если хотите контролировать, в каком потоке вызывается обработчик.
Эта функция была добавлена в Qt 6.0.
См. также then() и onFailed().
[since 6.1] template <typename Function, typename> QFuture<T> QFuture::onCanceled(QObject *context, Function &&handler)
Это перегруженная функция.
Прикрепляет обработчик отмены handler к этому будущему, который вызывается при отмене будущего. handler — это вызываемый объект, который не принимает аргументы. Он будет вызван в потоке объекта context. Это может быть полезно, если отмену необходимо обработать в определенном потоке.
Примечание: При вызове этого метода необходимо гарантировать, что context остается активным на протяжении всего выполнения цепочки.
См. документацию другой перегрузки для получения более подробной информации об handler.
Эта функция была добавлена в Qt 6.1.
См. также then() и onFailed().
[since 6.0] template <typename Function, typename> QFuture<T> QFuture::onFailed(Function &&handler)
Прикрепляет обработчик ошибок к этому будущему для обработки любых исключений. Возвращаемое будущее ведет себя точно так же, как и это будущее (имеет то же состояние и результат), если только это будущее не завершится ошибкой с исключением.
handler — это вызываемый объект, который принимает либо не принимает аргументы, чтобы фильтровать по определенным типам ошибок, аналогично оператору catch. Он возвращает значение типа, упакованного в этом будущем. После ошибки возвращаемое будущее упаковывает значение, возвращенное handler.
Обработчик будет вызван только в случае возникновения исключения. Если исключение возникает после того, как этот обработчик прикреплен, обработчик выполняется в том потоке, который сообщает о завершении будущего в результате исключения. Если обработчик прикреплен после того, как это будущее уже завершилось ошибкой, он будет вызван немедленно в потоке, в котором выполняется onFailed(). Поэтому обработчик не всегда может делать предположения о том, в каком потоке он будет выполняться. Используйте перегрузку, принимающую объект контекста, если хотите контролировать, в каком потоке вызывается обработчик.
В примере ниже показано, как прикрепить обработчик ошибок:
QFuture<int> future = ...;
auto resultFuture = future.then([](int res) {
...
throw Error();
...
}).onFailed([](const Error &e) {
// Handle exceptions of type Error
...
return -1;
}).onFailed([] {
// Handle all other types of errors
...
return -1;
});
auto result = resultFuture.result(); // result is -1 Если прикреплено несколько обработчиков, будет вызван первый обработчик, соответствующий типу возникшего исключения. Например:
QFuture<int> future = ...;
future.then([](int res) {
...
throw std::runtime_error("message");
...
}).onFailed([](const std::exception &e) {
// This handler will be invoked
}).onFailed([](const std::runtime_error &e) {
// This handler won't be invoked, because of the handler above.
}); Если ни один из обработчиков не соответствует типу возникшего исключения, исключение будет передано в результирующее будущее:
QFuture<int> future = ...;
auto resultFuture = future.then([](int res) {
...
throw Error("message");
...
}).onFailed([](const std::exception &e) {
// Won't be invoked
}).onFailed([](const QException &e) {
// Won't be invoked
});
try {
auto result = resultFuture.result();
} catch(...) {
// Handle the exception
} Примечание: Вы всегда можете прикрепить обработчик, не принимающий аргументы, для обработки всех типов исключений и избежать написания блока try-catch.
Эта функция была добавлена в Qt 6.0.
См. также then() и onCanceled().
[since 6.1] template <typename Function, typename> QFuture<T> QFuture::onFailed(QObject *context, Function &&handler)
Это перегруженная функция.
Прикрепляет обработчик ошибок к этому будущему для обработки любых исключений, которые поднимает будущее или которые уже были подняты. Возвращает QFuture того же типа, что и это будущее. Обработчик будет вызван только в случае исключения в потоке объекта context. Это может быть полезно, если ошибку необходимо обработать в определенном потоке. Например:
// somewhere in the main thread
auto future = QtConcurrent::run([] {
// This will run in a separate thread
...
throw std::exception();
}).onFailed(this, [] {
// Update UI elements
}); Обработчик ошибок, прикрепленный к QtConcurrent::run, обновляет элементы пользовательского интерфейса и не может быть вызван из потока, не относящегося к пользовательскому интерфейсу. Поэтому this предоставляется как контекст для .onFailed(), чтобы убедиться, что он будет вызван в главном потоке.
Примечание: При вызове этого метода необходимо гарантировать, что context остается активным на протяжении всего выполнения цепочки.
См. документацию другой перегрузки для получения более подробной информации об handler.
Эта функция была добавлена в Qt 6.1.
См. также then() и onCanceled().
int QFuture::progressMaximum() const
Возвращает максимальное значение progressValue().
См. также progressValue() и progressMinimum().
int QFuture::progressMinimum() const
Возвращает минимальное значение progressValue().
См. также progressValue() и progressMaximum().
QString QFuture::progressText() const
Возвращает (необязательное) текстовое представление прогресса, как сообщается асинхронным вычислением.
Обратите внимание, что не все вычисления предоставляют текстовое представление прогресса, и в этом случае функция может вернуть пустую строку.
int QFuture::progressValue() const
Возвращает текущее значение прогресса, которое находится между progressMinimum() и progressMaximum().
См. также progressMinimum() и progressMaximum().
template <typename U, typename> T QFuture::result() const
Возвращает первый результат в будущем. Если результат не доступен немедленно, эта функция заблокируется и будет ждать, пока результат не станет доступным. Это удобный метод для вызова resultAt(0). Обратите внимание, что result() возвращает копию хранящегося внутри результата. Если T — тип только для перемещения или вы не хотите копировать результат, используйте takeResult() вместо этого.
Примечание: Вызов result() приводит к неопределенному поведению, если isValid() возвращает false для этого QFuture.
См. также resultAt(), results() и takeResult().
template <typename U, typename> T QFuture::resultAt(int index) const
Возвращает результат в позиции index в будущем. Если результат не доступен немедленно, эта функция заблокируется и будет ждать, пока результат не станет доступным.
Примечание: Вызов resultAt() приводит к неопределенному поведению, если isValid() возвращает false для этого QFuture.
См. также result(), results(), takeResult() и resultCount().
int QFuture::resultCount() const
Возвращает количество непрерывных результатов, доступных в этом будущем. Фактическое количество сохраненных результатов может отличаться от этого значения из-за пробелов в наборе результатов. Безопасно итерировать по результатам от 0 до resultCount().
См. также result(), resultAt(), results() и takeResult().
template <typename U, typename> QList<T> QFuture::results() const
Возвращает все результаты из будущего. Если результаты не доступны немедленно, эта функция заблокируется и будет ждать, пока они не станут доступными. Обратите внимание, что results() возвращает копию хранящихся внутри результатов. Получение всех результатов типа только для перемещения T в данный момент не поддерживается. Однако вы по-прежнему можете перебирать список результатов только для перемещения, используя STL-стилевые итераторы или Java-стилевые итераторы.
Примечание: Вызов results() приводит к неопределённому поведению, если isValid() возвращает false для данного QFuture.
См. также result(), resultAt(), takeResult(), resultCount(), и isValid().
void QFuture::resume()
Возобновляет асинхронное вычисление, представленное будущим. Это метод удобства, который просто вызывает setSuspended(false).
См. также suspend().
[since 6.0] void QFuture::setSuspended(bool suspend)
Если suspend имеет значение true, эта функция приостанавливает асинхронное вычисление, представленное будущим. Если вычисление уже приостановлено, эта функция ничего не делает. QFutureWatcher немедленно не прекратит передачу сигналов готовности прогресса и результата, когда будущее приостанавливается. В момент приостановки могут продолжаться вычисления, которые невозможно остановить. Сигналы для таких вычислений всё ещё будут передаваться.
Если suspend имеет значение false, эта функция возобновляет асинхронное вычисление. Если вычисление ранее не было приостановлено, эта функция ничего не делает.
Обратите внимание, что не все вычисления можно приостановить. Например, QFuture, возвращённая QtConcurrent::run(), не может быть приостановлена; но QFuture, возвращённая QtConcurrent::mappedReduced(), может.
Эта функция была введена в Qt 6.0.
См. также isSuspended(), suspend(), resume(), и toggleSuspended().
[since 6.0] void QFuture::suspend()
Приостанавливает асинхронное вычисление, представленное этим будущим. Это метод удобства, который просто вызывает setSuspended(true).
Эта функция была введена в Qt 6.0.
См. также resume().
[since 6.0] template <typename U, typename> T QFuture::takeResult()
Вызывайте эту функцию только если isValid() возвращает true, в противном случае поведение неопределённо. Эта функция берёт (перемещает) первый результат из объекта QFuture, когда ожидается только один результат. Если есть другие результаты, они удаляются после взятия первого. Если результат немедленно недоступен, эта функция заблокируется и подождёт, пока результат станет доступным. QFuture попытается использовать семантику перемещения, если это возможно, и вернётся к копированию, если тип не может быть перемещён. После того, как результат был взят, isValid() будет оцениваться как false.
Примечание: QFuture в общем случае позволяет совместно использовать результаты между различными объектами QFuture (и потенциально между различными потоками). takeResult() была добавлена, чтобы QFuture также работала с типами, которые нельзя перемещать (например, std::unique_ptr), поэтому она предполагает, что только один поток может извлечь результаты из будущего и сделать это только один раз. Также обратите внимание, что взятие списка всех результатов в настоящее время не поддерживается. Тем не менее, вы всё ещё можете итерироваться по списку результатов, которые нельзя перемещать, используя итераторы в стиле STL или итераторы в стиле Java.
Эта функция была введена в Qt 6.0.
См. также result(), results(), resultAt(), и isValid().
[since 6.0] template <typename Function> QFuture<ResultType<Function> > QFuture::then(Function &&function)
Это перегруженная функция.
Подключает продолжение к этому будущему, позволяя цепочить несколько асинхронных вычислений, если это необходимо, с использованием политики Sync. function — вызываемый объект, который принимает аргумент типа, упакованного этим будущим, если у него есть результат (это не QFuture<void>). В противном случае он не принимает аргументов. Этот метод возвращает новое QFuture, которое упаковывает значение типа, возвращённого function. Возвращаемое будущее будет в неинициализированном состоянии до тех пор, пока присоединённое продолжение не будет вызвано или пока это будущее не завершится ошибкой или не будет отменено.
Примечание: Используйте другие перегрузки этого метода, если вам нужно запустить продолжение в отдельном потоке.
Вы можете цепочить несколько операций следующим образом:
QFuture<int> future = ...;
future.then([](int res1){ ... }).then([](int res2){ ... })... Или:
QFuture<void> future = ...;
future.then([](){ ... }).then([](){ ... })... Продолжение также может принимать аргумент QFuture (вместо его значения), представляющий предыдущее будущее. Это может быть полезно, если, например, QFuture имеет несколько результатов, и пользователь хочет получить к ним доступ внутри продолжения. Или пользователю нужно обработать исключение предыдущего будущего внутри продолжения, чтобы не прерывать цепочку нескольких продолжений. Например:
QFuture<int> future = ...;
future.then([](QFuture<int> f) {
try {
...
auto result = f.result();
...
} catch (QException &e) {
// handle the exception
}
}).then(...); Если предыдущее будущее бросает исключение, и оно не обрабатывается внутри продолжения, исключение будет передано в будущее продолжения, чтобы позволить вызывающей стороне обработать его:
QFuture<int> future = ...;
auto continuation = future.then([](int res1){ ... }).then([](int res2){ ... })...
...
// future throws an exception
try {
auto result = continuation.result();
} catch (QException &e) {
// handle the exception
} В этом случае вся цепочка продолжений будет прервана.
Примечание: Если это будущее отменяется, присоединённые к нему продолжения также будут отменены.
Эта функция была введена в Qt 6.0.
См. также onFailed() и onCanceled().
[since 6.0] template <typename Function> QFuture<ResultType<Function> > QFuture::then(QtFuture::Launch policy, Function &&function)
Это перегруженная функция.
Подключает продолжение к этому будущему, позволяя цепочить несколько асинхронных вычислений. Когда асинхронное вычисление, представленное этим будущим, завершается, function будет вызван в соответствии с заданной политикой запуска policy. Возвращается новое QFuture, представляющее результат продолжения.
В зависимости от policy, продолжение будет вызвано в том же потоке, что и это будущее, в новом потоке или унаследует политику запуска и пул потоков этого будущего. Если политика запуска не указана (см. перегрузку, принимающую только вызываемый объект), будет использоваться политика Sync.
В следующем примере оба продолжения будут вызваны в новом потоке (но в одном и том же).
QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... }).then([](int res2){ ... }); В следующем примере оба продолжения будут вызваны в новых потоках, используя тот же пул потоков.
QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... })
.then(QtFuture::Launch::Inherit, [](int res2){ ... }); См. документацию другой перегрузки для получения более подробной информации о function.
Эта функция была введена в Qt 6.0.
См. также onFailed() и onCanceled().
[since 6.0] template <typename Function> QFuture<ResultType<Function> > QFuture::then(QThreadPool *pool, Function &&function)
Это перегруженная функция.
Подключает продолжение к этому будущему, позволяя цепочить несколько асинхронных вычислений. Когда асинхронное вычисление, представленное этим будущим, завершается, function будет вызван в отдельном потоке, взятом из QThreadPool pool.
Эта функция была введена в Qt 6.0.
См. также onFailed() и onCanceled().
[since 6.1] template <typename Function> QFuture<ResultType<Function> > QFuture::then(QObject *context, Function &&function)
Это перегруженная функция.
Подключает продолжение к этому будущему, позволяя цепочить несколько асинхронных вычислений, если это необходимо. Когда асинхронное вычисление, представленное этим будущим, завершается, function будет вызван в потоке объекта context. Это может быть полезно, если продолжение нужно вызвать в определённом потоке. Например:
// somewhere in the main thread
auto future = QtConcurrent::run([] {
// This will run in a separate thread
...
}).then(this, [] {
// Update UI elements
}); Продолжение, присоединённое к QtConcurrent::run, обновляет элементы пользовательского интерфейса и не может быть вызвано из не-GUI-потока. Поэтому this предоставляется в качестве контекста для .then(), чтобы убедиться, что он будет вызван в главном потоке.
Следующие продолжения также будут вызваны из того же контекста, если не указан другой контекст или политика запуска:
auto future = QtConcurrent::run([] {
...
}).then(this, [] {
// Update UI elements
}).then([] {
// This will also run in the main thread
}); Это потому, что по умолчанию .then() вызывается из того же потока, что и предыдущий.
Но обратите внимание, что если продолжение присоединяется после того, как это будущее уже завершилось, оно будет вызвано немедленно, в потоке, который выполняет then():
QObject *context = ...;
auto future = cachedResultsReady ? QtFuture::makeReadyFuture(results)
: QtConcurrent::run([] { /* compute results */});
auto continuation = future.then(context, [] (Results results) {
// Runs in the context's thread
}).then([] {
// May or may not run in the context's thread
}); В приведённом примере, если cachedResultsReady является true, и возвращается готовое будущее, возможно, что первое .then() завершится до присоединения второго. В этом случае оно будет обработано в текущем потоке. Поэтому, на всякий случай, явно передавайте контекст.
Примечание: При вызове этого метода должно быть гарантировано, что context остаётся живым на протяжении всего выполнения цепочки.
Эта функция была введена в Qt 6.1.
См. также onFailed() и onCanceled().
[since 6.0] void QFuture::toggleSuspended()
Переключает приостановленное состояние асинхронного вычисления. Другими словами, если вычисление в настоящее время приостанавливается или приостановлено, вызов этой функции возобновляет его; если вычисление выполняется, оно приостанавливается. Это удобный метод для вызова setSuspended(!(isSuspending() || isSuspended())).
Эта функция была добавлена в Qt 6.0.
См. также setSuspended(), suspend() и resume().
void QFuture::waitForFinished()
Ожидает завершения асинхронного вычисления (включая отмененные cancel() вычисления), т.е. до тех пор, пока isFinished() не вернёт true.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qfuture.html