QFuture: failed vs cancelled
-
Imagine the code working with
QFuture:class Example : public QObject { public: Example(): QObject() { connect(&watcher_, &QFutureWatcher<int>::finished, this, &Example::jobFinished); } QFuture<int> runJobInAnotherThread() { QFuture<int> future = QtConcurrent::run([](QPromise<int>& promise) { while (!promise.isCanceled() /*&& job is not done*/) { //do job //!!!!MIGHT THROW QException HERE!!!! } promise.addResult(123); }); watcher_.setFuture(future); return future; } private: QFutureWatcher<int> watcher_; void jobFinished() { //"normal" and "exception" flow are processed here //but how to process the "cancel" flow? watcher_.isCanceled() can't be //used, as "exception" flow also makes isCanceled() return "true" try { int result = watcher_.result(); //process the result } catch (QException& ex) { //process the exception } } };auto example = new Example; QFuture<int> future = example.runJobInAnotherThread(); //future might be cancelled by the user here //future.cancel()Here we have a
QtConcurrent::runand aQFutureWatcher, waiting for the result on itsfinishedsignal.Inside the
finishedhandler, I need to check for three different cases:- normal
- background thread exception
- future canceled by the user
I can not find a way to check "exception" vs "cancellation", as they both do mark the future as
isCanceled()=true, and they both fail to retrieve any results from the future.Can anyone suggest a way?
-
Seems I found a way.
QFuture::isValid()can be used for what I need.void jobFinished() { if (!watcher_.future().isValid()) { //future was cancelled } try { int result = watcher_.result(); //process the result } catch (QException& ex) { //process the exception } } -
Hi,
Based on the setException doc, you should check the result. It shall contain the exception.
-
The problem is not to catch an exception. The problem is to distinguish exception from cancellation.
-
Shouldn't you handle that using the QFuture::onFailed and QFuture::onCanceled methods ?
-
Well.. Lots of code already written via
QFutureWatcher. So I was expecting to achieve the goal without rewriting much. -
Seems I found a way.
QFuture::isValid()can be used for what I need.void jobFinished() { if (!watcher_.future().isValid()) { //future was cancelled } try { int result = watcher_.result(); //process the result } catch (QException& ex) { //process the exception } }