Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Clear QFuture results for reusability in a class/object



  • I have an application that makes use of a number of QFutures for intense processing. Since these functions are repeatable, I create a class that allows me to continuously reuse the functionality.

    A simple example of what I am using is the following. Please note, this is a representation of what I intend, it is not my actual code.

    A brief overview:

    2 Futures, one runs after the other - these futures use member functions dependant on an instance for e.g. filtering. There are naturally more futures with different template types, this is simply an example. I will start by calling e.g. startProcessing() with some input, and await the result to be printed (in this case, or emitted via a signal).

    header

    //...
    QFuture<SomeType> futureFilterAction;
    QFuture<SomeType> futureMapAction;
    QFutureWatcher<SomeType> futureWatcherFilterAction;
    QFutureWatcher<SomeType> futureWatcherMapAction;
    //...
    

    impl class

    // filter member function
    bool ClassName::filterAction(const SomeType& someType) {
        // some internal filtering rules
        return true;
    } 
    
    // mapping member function
    SomeType ClassName::mapAction(const SomeType& someType) {
        // some internal mapping function(s)
    	SomeType t = ...
        return t;
    } 
    
    //... 
    void ClassName::startProcessing(QList<SomeType> someInputList) {
        
        // Perform action when finished
        connect(&futureWatcherFilterAction, &QFutureWatcher<SomeType>::finished, [this], [this]() { 
            // perform finishing actions & e.g. start map future with some result input
            startMapFuture(someResultInputToMap)
        });
    
        // Perform action when result is ready
        connect(&futureWatcherFilterAction, &QFutureWatcher<SomeType>::resultReadyAt, [this], [this](int indexOfResult) { 
            // do something with futureFilterAction.resultAt(indexOfResult)
            // perform some action e.g. add to some list with a mutex lock & unlock
        });
    	
    	// use std::bind for member function
        futureFilterAction = QtConcurrent::filter(someInputList, std::bind(&ClassName::filterAction, this, std::placeholders::_1));
        futureWatcherFilterAction.setFuture(futureFilterAction);
    }
    
    void ClassName::startMapFuture(QList<SomeType> someInputList) {
    
        // Perform action when finished
        connect(&futureWatcherMapAction, &QFutureWatcher<SomeType>::finished, [this], [this]() { 
            // perform finishing actions & e.g. start map future with some result input
            printResults(someResultInputToMap)
        });
    
        // Perform action when result is ready
        connect(&futureWatcherMapAction, &QFutureWatcher<SomeType>::resultReadyAt, [this], [this](int indexOfResult) { 
            // do something with futureMapAction.resultAt(indexOfResult)
            // perform some action e.g. add to some list with a mutex lock & unlock
        });
    	
    	// use std::bind for member function
        futureMapAction = QtConcurrent::mapped(someInputList, std::bind(&ClassName::mapAction, this, std::placeholders::_1));
        futureWatcherMapAction.setFuture(futureMapAction);
    }
    //...
    

    This code may be called multiple times throughout the application lifespan. If I run this once, it performs the actions 100% correctly i.e. all the expected results are returned and stored when getting the result from QFuture::resultAt(int) function call.

    Problem

    When calling a QFuture for the second time and on requesting the result from that already run future, it returns the results held internally in addition to the new results.

    e.g. if I run the following:

    classNameInstance.startProcessing(someInputList) it will print

    Line 1
    Line 2
    Line 3
    

    Then, if I call classNameInstance.startProcessing(aCompletelyNewInputList), it will print

    Line 1   < ---- stored internally in QFuture (are returned & printed first)
    Line 2   < ---- 
    Line 3   < ---- 
    Text 1   < ---- New results which I expect start here
    Text 3   < ---- 
    Text 5   < ---- 
    Text 7   < ---- 
    

    Question:

    This brings me to my question, how can I clear a QFuture's results? What is the suggested usage for QFutures in this scenario?



  • @CybeX said in Clear QFuture results for reusability in a class/object:

    QFuture<SomeType> futureFilterAction;

    The docs say it can be copied so this should clear it out:

    {
            QFuture<SomeType> future;
    
            // ...
    
            future = QFuture<SomeType>();
    }
    


  • @CybeX said in Clear QFuture results for reusability in a class/object:

    QFuture<SomeType> futureFilterAction;

    The docs say it can be copied so this should clear it out:

    {
            QFuture<SomeType> future;
    
            // ...
    
            future = QFuture<SomeType>();
    }
    


  • @fcarney

    So I was trying to reassign it, etc but I am not sure why I didn't take another look at the docs for simply recreating it...thank you!



  • @CybeX said in Clear QFuture results for reusability in a class/object:

    not sure why I didn't take another look at the docs

    Sometimes we don't see this stuff even if we do look again. Second eyes help. Half the time I post something, then solve it within minutes. Glad it helped you.


Log in to reply