Important: Please read the Qt Code of Conduct -

Problem propagating exceptions from QtConcurrent::map()

  • I've run into an issue with QtConcurrent::map() when I try to throw a QtConcurrent::Exception from within a thread. From the documentation, the exception should be thrown in the main thread when result(), results(), resultAt(), or waitForFinished() are called on the QFuture returned by map. However, when using a QFuture<void> - the type returned from map() - the only option is waitForFinished() since there are no results stored within the QFuture itself.

    The problem with waitForFinished() is that it blocks until the asynchronous operation finishes, which is problematic because I need to be able to do progress reporting as well as being able to cancel the algorithm if the user requests it. I've tried to circumvent this by creating a QFutureWatcher and registering the progressValueChanged() signal to a slot that can update, but it appears that this doesn't actually respond when the QFuture is waiting for the operation to complete.

    I have also tried converting to using mapped() instead of map(), but it gives me a compilation error when I match the QFuture's template to the type returned by mapped():
    @QList<QPair<int, QList<int> > > locations; // list to be processed asynchronously
    QFuture<const QPair<int, QList<int> > &> rx = QtConcurrent::mapped(locations, rxMap); // begin the map operation@

    This causes the error: error C2528: 'result' : pointer to reference is illegal

    Is there an alternative way to do this? I tried (briefly) to subclass QFuture in order to add functionality to throw its exceptions in a way other than just waitForFinished() but I didn't have much luck. The current structure of the program is to have a loop that calls QThread::yieldCurrentThread() while QFuture::isRunning() is true, which allows for progress reporting, but exceptions do not get thrown from within the threads. I'd appreciate any feedback.

  • Further investigation shows that the person who implemented the code did some typedef stuff that was throwing me off in trying to convert this to mapped() rather than map(). However, it still seems like it would be nice to have some functionality where exceptions can be sent to and handled by the main thread rather than either having to used mapped() to arbitrarily access the results or by blocking with waitForFinished().

Log in to reply