Background
I have a QObject (myClass
) that runs in its own thread. The UI can trigger a time consuming slot in myClass
. This slot will process stuff, update the UI, process more stuff then updates variables used for background processing. If the slot is triggered faster than it can process, the first UI update will occur fast, but subsequent updates will have to wait (as myClass
is still bust processing y()
& z()
).
void myClass::mySlot() {
x(); // Fast
emit updateUI();
y(); // Slow
z(); // Slow
emit processingComplete();
}
To overcome this I've used QtConcurrent::run
for the slow processing so that subsequent updates also update the UI fast (as they don't have to wait for for y()
& z()
).
void myClass::mySlot() {
x(); // Fast
emit updateUI();
// future is a member variable of myClass of type QFuture<void>
future = QtConcurrent::run([&]() {
y(); // Slow
z(); // Slow
emit processingComplete();
});
}
I've tried to make the code cleaner by using cancel()
if the thread is still running but it fails as "... the future returned by QtConcurrent::run() cannot be canceled"
...
emit updateUI();
if(future.isRunning())
future.cancel();
future.waitForFinished()
future = QtConcurrent::run([&]() {
...
Questions
- Is reassignment of a running
QFuture<T>
safe when usingQMutexLocker
? This answer states that it's safe but doesn't cover mutexes. - Will the "overwritten" threads still execute in the background, orphaned, until they time out or will they stop executing regardless of the line they're on?
- Can a
QFuture<T>
be restarted from the beginning of its execution (if yes, can it be restarted regardless of its state, running/finished/canceled/paused)? - Are there other workarounds if reassigning isn't safe? (I can't use this solution as
y()
&z()
are linear, not loops).
Assume the above code is the only place that accesses the future
variable.