Der Faden und MyClass
Instanzen sowohl live als im selben Thread - wahrscheinlich der Haupt-Thread:
MyClass::MyClass() {
...
Q_ASSERT(this->thread() == thread.thread());
Doch die Ereignisse, die Sie dem Arbeiter Objekt an den Worker-Thread gehen sind Warteschlangen:
Die Verbindung in der Warteschlange ist genau das Falsche, denn sobald Sie auf den Arbeitsthread warten, wird die Ereignisschleife des Hauptthreads nicht ausgeführt und keine weiteren Ereignisse an den Thread ausgegeben. Der Aufruf quit
wird niemals zugestellt, da er im Hauptthread geliefert wird, der Hauptthread jedoch blockiert ist.
Nutzen Sie stattdessen den Vorteil quit
als threadsichere Methode. Nennen Sie es von der Arbeiter-Thread selbst:
// vvvvvvv thread context object for the call
connect(this, &MyClass::signalFinish, &worker, [this]{ thread.quit(); });
// the `quit()` will execute in `worker.thread()`
Beachten Sie, dass der Thread-Kontext-Objekt ist ein Objekt, dessen thread()
wird der Anruf in ausgeführt werden Es sollte nicht sein ein QThread
Beispiel in den meisten Fällen.!
Wenn die signalFinish
ausgegeben wird, wird ein QMetaCallEvent
, der den Funktor oben trägt, in die Warteschlange des Arbeitsthreads eingereiht und wird ausgeführt, nachdem alle bestehenden Anruf- (und andere) Ereignisse zuerst verarbeitet wurden.
Da Sie im Hauptthread finish
aufrufen, möchten Sie wahrscheinlich nicht auf den Thread warten, da dies die GUI blockiert und Ihre Anwendung nicht mehr reagiert.
Da es so aussieht, als würden Sie einem Worker-Thread Job-Artikel senden, könnten Sie besser von QtConcurrent::run
bedient werden, die Job-Artikel an einen Thread-Pool übergibt und alle Threads für Sie übernimmt. Ein vollständiges Beispiel finden Sie unter this answer. Siehe this answer und that answer für einige verwandte Leckerbissen.
haben Sie vielleicht einen 'QuitThread'-Slot in Ihrem Worker (der den aktuellen Thread' QThread :: currentThread() -> quit(); ') beendet und stattdessen eine Verbindung zum' thread's 'quit herstellt 'Schlitz. Auf diese Weise wird der 'QuitThread'-Slot ausgeführt, nachdem alle zuvor in der Warteschlange befindlichen Slots ausgeführt wurden. . . – Mike