QThread: Making parallel execution with GUI-Feedback blocking?
#Scenario#

Lets say, I have a procedure called `parallelRun`. It would take a list of workers, each having a `getWorkAmount():int`, a `run()` method, a `finished()` signal and a `cancel()` slot:

    void parallelRun( std::vector< Worker* > workers );

Its implementation should:

##1. Open a `QPogressDialog`:

    unsigned int totalWorkAmount = 0;
    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        totalWorkAmount += ( **it ).getWorkAmount();
    }
    
    LoadUI ui( 0, totalWorkAmount, this );

with

	class LoadUI : public QObject
	{
		Q_OBJECT
		
	public:
	
		LoadUI( int min, int max, QWidget* modalParent )
			: totalProgres( 0 )
			, progressDlg( "Working", "Abort", min, max, modalParent )
		{
			connect( &progressDlg, SIGNAL( canceled() ), this, SLOT( cancel() ) );

			progressDlg.setWindowModality( Qt::WindowModal );
			progressDlg.show();
		}
		
		bool wasCanceled() const
		{
			return progressDlg.wasCanceled();
		}

	public slots:

		void progress( int amount )
		{
			totalProgres += amount;

			progressDlg.setValue( totalProgres );
			progressDlg.update();

			QApplication::processEvents();
		}

	signals:

		void canceled();

	private slots:

		void cancel()
		{
			emit canceled();
		}

	private:

		int totalProgres;
		QProgressDialog progressDlg;
	}

##2. Create one thread for each worker

    std::vector< std::unique_ptr< QThread > > threads;
    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        std::unique_ptr< QThread > thread( new QThread() );

        Worker* const worker = *it;
        worker->moveToThread( thread.get() );

        QObject::connect( worker, SIGNAL( finished() ), thread.get(), SLOT( quit() ) );
        QObject::connect( &ui, SIGNAL( canceled() ), worker, SLOT( cancel() ) );
        QObject::connect( *it, SIGNAL( progressed( int ) ), &ui, SLOT( progress( int ) ) );

        thread->start( priority );

        threads.push_back( std::move( thread ) );
    }

##3. Run them simultaneously

    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        QMetaObject::invokeMethod( *it, "run", Qt::QueuedConnection );
    }

`load()` is run when the user clicks an UI-button.

# Problem

How am I supposed to extend this code, if I want to make `parallelRun` block until all workers are finished, without freezing the `QProgressDialog`?

## Deliberations

### Using a barrier

I tried adding the following code at the end of the `parallelRun` routine:

    QApplication::processEvents();
    for( auto it = threads.begin(); it != threads.end(); ++it )
    {
        ( **it ).wait();
    }

The impact of this few lines of extra-code is, that `LoadUI::progress` is *never entered*, since the GUI-thread is *asleep* and therefore it's event loop isn't processed: In Qt, signals are delivered to slots by posting them to the event loop of the thread, associated to the object the slot belongs to. This is why the `progressed` signal of a worker is never delivered.

I think, the appropriate solution would be to run `QApplication::processEvents()` *within the GUI-thread* anytime a `progressed` signal is emitted by a worker. On the other hand, I guess this cannot be done, since the GUI-thread is asleep.

### Another possible solution

Another possible solution would be to use *active waiting* instead of the barrier:

    for( auto it = threads.begin(); it != threads.end(); ++it )
    {
        if( !( **it ).isFinished() )
        {
            QApplication::processEvents();
        }
    }

I don't think that this is a nice solution, but it would work - if only `isFinished` would return `false`, as expected. For reasons I'm not aware of its return value is `true`, although the thread is still running, isn't it?

Thanks in advance!
QThread: Making parallel execution with GUI-Feedback blocking?
===

#Scenario#

Lets say, I have a procedure called `parallelRun`. It would take a list of workers, each having a `getWorkAmount():int`, a `run()` method, a `finished()` signal and a `cancel()` slot:

    void parallelRun( std::vector< Worker* > workers );

Its implementation should:

##1. Open a `QPogressDialog`:

    unsigned int totalWorkAmount = 0;
    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        totalWorkAmount += ( **it ).getWorkAmount();
    }
    
    LoadUI ui( 0, totalWorkAmount, this );

with

	class LoadUI : public QObject
	{
		Q_OBJECT
		
	public:
	
		LoadUI( int min, int max, QWidget* modalParent )
			: totalProgres( 0 )
			, progressDlg( "Working", "Abort", min, max, modalParent )
		{
			connect( &progressDlg, SIGNAL( canceled() ), this, SLOT( cancel() ) );

			progressDlg.setWindowModality( Qt::WindowModal );
			progressDlg.show();
		}
		
		bool wasCanceled() const
		{
			return progressDlg.wasCanceled();
		}

	public slots:

		void progress( int amount )
		{
			totalProgres += amount;

			progressDlg.setValue( totalProgres );
			progressDlg.update();

			QApplication::processEvents();
		}

	signals:

		void canceled();

	private slots:

		void cancel()
		{
			emit canceled();
		}

	private:

		int totalProgres;
		QProgressDialog progressDlg;
	}

##2. Create one thread for each worker

    std::vector< std::unique_ptr< QThread > > threads;
    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        std::unique_ptr< QThread > thread( new QThread() );

        Worker* const worker = *it;
        worker->moveToThread( thread.get() );

        QObject::connect( worker, SIGNAL( finished() ), thread.get(), SLOT( quit() ) );
        QObject::connect( &ui, SIGNAL( canceled() ), worker, SLOT( cancel() ) );
        QObject::connect( *it, SIGNAL( progressed( int ) ), &ui, SLOT( progress( int ) ) );

        thread->start( priority );

        threads.push_back( std::move( thread ) );
    }

##3. Run them simultaneously

    for( auto it = workers.begin(); it != workers.end(); ++it )
    {
        QMetaObject::invokeMethod( *it, "run", Qt::QueuedConnection );
    }

`load()` is run when the user clicks an UI-button.

# Problem

How am I supposed to extend this code, if I want to make `parallelRun` block until all workers are finished, without freezing the `QProgressDialog`?

## Deliberations

### Using a barrier

I tried adding the following code at the end of the `parallelRun` routine:

    QApplication::processEvents();
    for( auto it = threads.begin(); it != threads.end(); ++it )
    {
        ( **it ).wait();
    }

The impact of this few lines of extra-code is, that `LoadUI::progress` is *never entered*, since the GUI-thread is *asleep* and therefore it's event loop isn't processed: In Qt, signals are delivered to slots by posting them to the event loop of the thread, associated to the object the slot belongs to. This is why the `progressed` signal of a worker is never delivered.

I think, the appropriate solution would be to run `QApplication::processEvents()` *within the GUI-thread* anytime a `progressed` signal is emitted by a worker. On the other hand, I guess this cannot be done, since the GUI-thread is asleep.

### Another possible solution

Another possible solution would be to use *active waiting* instead of the barrier:

    for( auto it = threads.begin(); it != threads.end(); ++it )
    {
        if( !( **it ).isFinished() )
        {
            QApplication::processEvents();
        }
    }

I don't think that this is a nice solution, but it would work - if only `isFinished` would return `false`, as expected. For reasons I'm not aware of its return value is `true`, although the thread is still running, isn't it?

Thanks in advance!