Seite 1 von 1

Zeitintensive Function in Thread "kapseln" ?

Verfasst: 1. Dezember 2007 21:47
von comer352l
Hallo zusammen,

ich muss in meinem Programm mehrfach eine function aufrufen, die einige Sekunden benötigt, um den Rückgabewert zu liefern. Dabei handelt es sich um eine Read-Funktion, ueber die ich Daten von einem Messgerät abfragen kann (stammt aus einer externen Geräte-Bibliothek und kann daher nicht geändert werden).
Dabei friert mir natürlich jedesmal das GUI (QMainWindow) im Hauptthread ein.
Mein momentaner Ansatz besteht darin, dass Ganze in einem Thread zu kapseln, hier komme ich aber im Augenblick nicht weiter:
Ich möchte das Problem eigentlich nicht per Signals/Slots lösen, weil
1) die Read-Funktionan an den verschiedensten Stellen im Programm aufgerufen wird
2.) die Weiterverarbeitung des Rückgabewerts vom Verwendungs-Kontext abhängt
Das würde praktisch dazu führen, dass ich entweder unzählige zusäztliche Slot-functions brauche oder aber dem Thread Informationen darüber mit mitgeben muss, was mit dem Ergebnis (Rückgabewert) geschehen soll. Diese Informationen könnte dann der "empfangende" Slot des Hauptthreads auswerten. In jedem Fall würde das Programm aber dadurch sehr kompliziert bzw. unübersichtlich...
Es wäre also wünschenswert, den Rückgabewert in der gleichen Funktion auszuwerten, die auch die Read-Funktion aufruft.

Den Lese-Vorgang (Aufruf der Read-Funktion) in einem separaten Thread ablaufen zu lassen ist zwar 'ne leichte Übung, aber wenn ich mit wait()-Methode auf das Ende des Threads warte, friert mir mein GUI natürlich genauso ein...

Bin für jeden Lösungs-Ansatz dankbar...

Verfasst: 1. Dezember 2007 23:49
von upsala
Über ein QCustomEvent könntest du den Empfänger mitgeben, event. ist dies leichter umzusetzen.

Verfasst: 4. Dezember 2007 13:13
von comer352l
Also ich habe das jetzt mal (vorläufig) so gelöst:
(Der Einfachheit halber habe ich das Problem im folgenden Beispiel auf eine einfache Warte-Funktion reduziert)

Code: Alles auswählen

class WThread : public QThread
{
   Q_OBJECT

private:
   int _ms;

public:
   WThread(int ms) { _ms = ms; };
   void run() { msleep(_ms); };
};


class WaitClass : private QEventLoop
{
   Q_OBJECT

public:
   WaitClass(int ms) : QEventLoop()
   {
      WThread wt(ms);
      connect( &wt, SIGNAL( finished() ), this, SLOT( exit() ) );
      wt.start();
      exec();
   };
};


class test
{
public:
    static void nbwait(int ms) { WaitClass wc(ms); };
};
Durch den Aufruf von

Code: Alles auswählen

test::nbwait(5000);
wird somit 5000ms gewartet, ohne dass das GUI einfriert (im Gegensatz zum direkten Aufruf von sleep()).
Ist zwar sicherlich nicht schön, klappt aber wunderbar...

In meinem konkreten Fall führe ich anstelle der sleep()-Funktion meine Read()-Funktion aus und es kommen noch die Rückgabewerte hinzu...

Bin dennoch weiter für jede Anregung dankbar !

Verfasst: 4. Dezember 2007 14:07
von solarix
bei sowas bluten mir die Augen.. aber wenn schon gebastel (sleep waehrend Applikation), dann eher so:

Code: Alles auswählen

void mySleep (int ms)
{
   QTime timer;
   timer.start();
   do {
          QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
          QTest::qSleep(10);
   } while (timer.elapsed() < ms);
}
(aus QTest::qWait())

hth...

Verfasst: 4. Dezember 2007 15:47
von comer352l
solarix hat geschrieben:bei sowas bluten mir die Augen.. aber wenn schon gebastel (sleep waehrend Applikation), dann eher so:

Code: Alles auswählen

void mySleep (int ms)
{
   QTime timer;
   timer.start();
   do {
          QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
          QTest::qSleep(10);
   } while (timer.elapsed() < ms);
}
(aus QTest::qWait())

hth...
Auch ein nettes Beispiel für 'ne Wait-Funktion... :D

Ich darf allerdings daran erinnern, dass es in meinem konkreten Fall nicht um eine (sinnlose) Warte-Funktion geht (sollte nur als vereinfachtes Beispiel dienen), sondern um eine Read-Funktion.

Die Idee mit dem Timer ist aber zumindest ein neuer Denk-Anstoss, den ich mir mal durch den Kopf gehen lassen werde... Danke !

Manchmal kommt man eben nicht ohne Bastelei aus.
Dass Grundproblem ist doch die schlecht bzw. falsch implementierte Read()-Funktion, die ich verwenden muss, und die ist leider fix... :(