Gleichzeitige Aufgabe
QtConcurrent::task bietet eine alternative Schnittstelle für die Ausführung einer Aufgabe in einem separaten Thread. Der Rückgabewert der Funktion wird über die API QFuture zur Verfügung gestellt.
Wenn Sie eine Funktion einfach in einem separaten Thread ausführen möchten, ohne Parameter anzupassen, verwenden Sie QtConcurrent::run, da Sie so weniger Code schreiben müssen. QtConcurrent::task ist für Fälle gedacht, in denen Sie zusätzliche Konfigurationsschritte durchführen müssen.
Diese Funktion ist ein Teil des Qt Concurrent Frameworks.
Fließende Schnittstelle
Die Funktion QtConcurrent::task gibt eine Instanz einer Hilfsklasse namens QtConcurrent::QTaskBuilder zurück. Normalerweise müssen Sie eine Instanz dieser Klasse nicht manuell erstellen. Die QtConcurrent::QTaskBuilder bietet eine Schnittstelle, um verschiedene Aufgabenparameter auf eine kettenartige Weise anzupassen. Dieser Ansatz wird als fließende Schnittstelle bezeichnet.
Sie können einfach die benötigten Parameter einstellen und dann eine Aufgabe starten. Um die Konfiguration eines Tasks abzuschließen, müssen Sie die Funktion QtConcurrent::QTaskBuilder::spawn aufrufen. Diese Funktion ist nicht blockierend (d. h. sie gibt sofort ein Future-Objekt zurück), aber es ist nicht garantiert, dass die Aufgabe sofort gestartet wird. Sie können die Klassen QFuture und QFutureWatcher verwenden, um den Status des Tasks zu überwachen.
Weitere Beispiele und Erklärungen finden Sie weiter unten.
Ausführen eines Tasks in einem separaten Thread
Um eine Funktion in einem anderen Thread auszuführen, verwenden Sie QtConcurrent::QTaskBuilder::spawn:
QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn();
Dadurch wird eine Lambda-Funktion in einem separaten Thread ausgeführt, der aus dem Standard-Thread QThreadPool stammt.
Übergabe von Argumenten an die Aufgabe
Um eine Funktion mit Argumenten aufzurufen, übergeben Sie diese an QtConcurrent::QTaskBuilder::withArguments:
auto task = [](const QString &s){ qDebug() << ("Hello, " + s); }; QtConcurrent::task(std::move(task)) .withArguments("world!") .spawn();
An dem Punkt, an dem QtConcurrent::QTaskBuilder::withArguments aufgerufen wird, wird eine Kopie jedes Arguments erstellt, und diese Werte werden an den Thread übergeben, wenn dieser mit der Ausführung der Aufgabe beginnt. Änderungen, die nach dem Aufruf von QtConcurrent::QTaskBuilder::withArguments an den Argumenten vorgenommen werden, sind für den Thread nicht sichtbar.
Wenn Sie eine Funktion ausführen möchten, die Argumente per Verweis akzeptiert, sollten Sie std::ref/cref-Hilfsfunktionen verwenden. Diese Funktionen erzeugen dünne Hüllen um die übergebenen Argumente:
QString s("Hello, "); QtConcurrent::task([](QString &s){ s.append("world!"); }) .withArguments(std::ref(s)) .spawn();
Stellen Sie sicher, dass alle umhüllten Objekte lange genug leben. Es kann zu undefiniertem Verhalten kommen, wenn eine Aufgabe das von std::ref/cref umhüllte Objekt überlebt.
Rückgabe von Werten aus der Aufgabe
Sie können das Ergebnis eines Tasks mit der API QFuture erhalten:
auto future = QtConcurrent::task([]{ return 42; }).spawn(); auto result = future.result(); // result == 42
Beachten Sie, dass QFuture::result() ein blockierender Aufruf ist, der darauf wartet, dass das Ergebnis verfügbar wird. Verwenden Sie QFutureWatcher, um eine Benachrichtigung zu erhalten, wenn die Ausführung der Aufgabe beendet ist und das Ergebnis verfügbar ist.
Falls Sie ein Ergebnis an eine andere asynchrone Aufgabe weitergeben möchten, können Sie QFuture::then() verwenden, um eine Kette abhängiger Aufgaben zu erstellen. Weitere Einzelheiten finden Sie in der Dokumentation QFuture.
Zusätzliche API-Funktionen
Verwendung verschiedener Typen von Callable Objects
Streng genommen können Sie alle Arten von Aufgaben und Argumenten verwenden, die die folgende Bedingung erfüllen:
std::is_invocable_v<std::decay_t<Task>, std::decay_t<Args>...>
Sie können eine freie Funktion verwenden:
QVariant value(42); auto result = QtConcurrent::task([](const QVariant &var){return qvariant_cast<int>(var);}) .withArguments(value) .spawn() .result(); // result == 42
Sie können eine Mitgliedsfunktion verwenden:
QString result("Hello, world!"); QtConcurrent::task(&QString::chop) .withArguments(&result, 8) .spawn() .waitForFinished(); // result == "Hello"
Sie können ein aufrufbares Objekt mit einem Operator() verwenden:
auto result = QtConcurrent::task(std::plus<int>()) .withArguments(40, 2) .spawn() .result() // result == 42
Wenn Sie ein vorhandenes aufrufbares Objekt verwenden wollen, müssen Sie es entweder nach QtConcurrent::task kopieren/verschieben oder mit std::ref/cref umhüllen:
struct CallableWithState { void operator()(int newState) { state = newState; } // ... }; // ... CallableWithState object; QtConcurrent::task(std::ref(object)) .withArguments(42) .spawn() .waitForFinished(); // The object's state is set to 42
Verwendung eines benutzerdefinierten Thread-Pools
Sie können einen eigenen Thread-Pool angeben:
QThreadPool pool; QtConcurrent::task([]{ return 42; }).onThreadPool(pool).spawn();
Priorität für eine Task festlegen
Sie können die Priorität für eine Task festlegen:
QtConcurrent::task([]{ return 42; }).withPriority(10).spawn();
Wenn Sie kein Future-Objekt benötigen, können Sie QtConcurrent::QTaskBuilder::spawn(QtConcurrent::FutureResult::Ignore) aufrufen:
QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn(FutureResult::Ignore);
Sie können auf das mit der Aufgabe verknüpfte promise-Objekt zugreifen, indem Sie innerhalb der Funktion ein zusätzliches Argument vom Typ QPromise<T> &
definieren. Dieses zusätzliche Argument muss das erste Argument sein, das an die Funktion übergeben wird, und wie im Modus Concurrent Run With Promise wird erwartet, dass die Funktion den Typ void zurückgibt. Die Ergebnismeldung erfolgt über die API QPromise:
void increment(QPromise<int> &promise, int i) { promise.addResult(i + 1); } int result = QtConcurrent::task(&increment).withArguments(10).spawn().result(); // result == 11
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.