Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. German
  4. QThread richtig einsetzen?
Forum Updated to NodeBB v4.3 + New Features

QThread richtig einsetzen?

Scheduled Pinned Locked Moved Solved German
39 Posts 3 Posters 17.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Galilio
    wrote on last edited by
    #15

    @J-Hilk

    Kannst du bitte mich helfen ?
    Ich komme echt gar nicht weiter und weiss es nicht was und wo ist das Problem?

    Danke

    J.HilkJ 1 Reply Last reply
    0
    • G Galilio

      @J-Hilk

      Kannst du bitte mich helfen ?
      Ich komme echt gar nicht weiter und weiss es nicht was und wo ist das Problem?

      Danke

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #16

      @Galilio
      hi, kommt das Oszilloskop mit eigenen dll's die du einbindest?

      So ein crash in Debug aber nicht in Release kann damit zusammen hängen, wenn zum Beipspeil ein Object in einer dll erzeugt und von einer anderen zerstört wird. Zugewiesener Speicher sollte immer immer von dem Modul freigegeben werden der ihn auch reseverviert.

      Man braucht ein wenig mehr Info, poste doch mal mehr vom Stacktrace und wenn möglich mehr vom problem-Code als eine Zeile.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      G 2 Replies Last reply
      0
      • J.HilkJ J.Hilk

        @Galilio
        hi, kommt das Oszilloskop mit eigenen dll's die du einbindest?

        So ein crash in Debug aber nicht in Release kann damit zusammen hängen, wenn zum Beipspeil ein Object in einer dll erzeugt und von einer anderen zerstört wird. Zugewiesener Speicher sollte immer immer von dem Modul freigegeben werden der ihn auch reseverviert.

        Man braucht ein wenig mehr Info, poste doch mal mehr vom Stacktrace und wenn möglich mehr vom problem-Code als eine Zeile.

        G Offline
        G Offline
        Galilio
        wrote on last edited by
        #17

        @J.Hilk said in QThread richtig einsetzen?:

        hi, kommt das Oszilloskop mit eigenen dll's die du einbindest?

        Was meinst du genau?
        Um die verbindung zu Oszilloskop zu ermöglichen wurde diese Class geschrieben.
        Also es gibt keine andere DLL, die verwendet wurde.
        Eine Sache noch: Bei Visual Studio 2008 und Qt4.8 Plugin habe ich das Problem nicht.

        So ein crash in Debug aber nicht in Release kann damit zusammen hängen, wenn zum Beipspeil ein Object in einer dll erzeugt und von einer anderen zerstört wird. Zugewiesener Speicher sollte immer immer von dem Modul freigegeben werden der ihn auch reseverviert.

        Ich glaube dises Fall trifft mich nicht.

        Man braucht ein wenig mehr Info, poste doch mal mehr vom Stacktrace und wenn möglich mehr vom problem-Code als eine Zeile

        1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @Galilio
          hi, kommt das Oszilloskop mit eigenen dll's die du einbindest?

          So ein crash in Debug aber nicht in Release kann damit zusammen hängen, wenn zum Beipspeil ein Object in einer dll erzeugt und von einer anderen zerstört wird. Zugewiesener Speicher sollte immer immer von dem Modul freigegeben werden der ihn auch reseverviert.

          Man braucht ein wenig mehr Info, poste doch mal mehr vom Stacktrace und wenn möglich mehr vom problem-Code als eine Zeile.

          G Offline
          G Offline
          Galilio
          wrote on last edited by
          #18

          @J.Hilk
          Kannst du bitte mich auf die Sprünge helfen?
          Ich habe es so angefangen:

          class QTcpSocket;
           
          class CAgilentLan : public QObject
          {
          	Q_OBJECT
           
          public:
           ...
              CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false);
              ~CAgilentLan();
           
          ...
              t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p);
           ..
           
          public slots:
              void AgilentStart();
           
          
          };
          

          Die run() Methode umbenannt und zu einen Slot deklariert.
          Mir ist dann nicht ganz klar wie soll ich die restlichen Methoden zu SLOT und SIGNAL einbinden kann?
          In der alte Version was diese Methode :

          t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p);
          
          

          Zentral. Das heisst jede aufruf diese Methode verusacht eine automatische aufruf der run() Methode.
          Ich will weiterhin dieses Ablauf beibehalten damit die Änderung minimal bleibt.
          Dir danke ich in voraus

          J.HilkJ 1 Reply Last reply
          0
          • G Galilio

            @J.Hilk
            Kannst du bitte mich auf die Sprünge helfen?
            Ich habe es so angefangen:

            class QTcpSocket;
             
            class CAgilentLan : public QObject
            {
            	Q_OBJECT
             
            public:
             ...
                CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false);
                ~CAgilentLan();
             
            ...
                t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p);
             ..
             
            public slots:
                void AgilentStart();
             
            
            };
            

            Die run() Methode umbenannt und zu einen Slot deklariert.
            Mir ist dann nicht ganz klar wie soll ich die restlichen Methoden zu SLOT und SIGNAL einbinden kann?
            In der alte Version was diese Methode :

            t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p);
            
            

            Zentral. Das heisst jede aufruf diese Methode verusacht eine automatische aufruf der run() Methode.
            Ich will weiterhin dieses Ablauf beibehalten damit die Änderung minimal bleibt.
            Dir danke ich in voraus

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #19

            @Galilio ich guck mal ob ich heute Abend Zeit finde eine ausführliche Antwort zu erstellen.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            G 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @Galilio ich guck mal ob ich heute Abend Zeit finde eine ausführliche Antwort zu erstellen.

              G Offline
              G Offline
              Galilio
              wrote on last edited by
              #20

              @J.Hilk
              Hi
              danke dir
              Eigentlich in jede Stelle wo das Object:

              CAgilentLan
              

              aufegerufen wird muss ich folgende schreiben:

              	QThread * workerThread = new QThread();
              	CAgilentLan *workerObject = new CAgilentLan(.....);
              	workerObject->moveToThread(workerThread);
              	connect(workerThread, &QThread::started, workerObject, &CAgilentLan::agilentStart);
                     // aufräumen
              	connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
              	connect(workerThread, &QThread::finished, workerObject, &CAgilentLan::deleteLater);
              

              Ist das so richtig?

              G 1 Reply Last reply
              0
              • G Galilio

                @J.Hilk
                Hi
                danke dir
                Eigentlich in jede Stelle wo das Object:

                CAgilentLan
                

                aufegerufen wird muss ich folgende schreiben:

                	QThread * workerThread = new QThread();
                	CAgilentLan *workerObject = new CAgilentLan(.....);
                	workerObject->moveToThread(workerThread);
                	connect(workerThread, &QThread::started, workerObject, &CAgilentLan::agilentStart);
                       // aufräumen
                	connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
                	connect(workerThread, &QThread::finished, workerObject, &CAgilentLan::deleteLater);
                

                Ist das so richtig?

                G Offline
                G Offline
                Galilio
                wrote on last edited by Galilio
                #21

                @J-Hilk
                noch eine Frage, da ich in das class

                CAgilentLan
                

                viele exception abfänge z.B:

                throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error"));
                

                Wie soll ich solche Exception mit Signal und Slot steuern?
                Danke

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  Galilio
                  wrote on last edited by Galilio
                  #22

                  Hallo,

                  ich habe es jetzt fast geschafft.
                  Ich habe in meine Application wo das Object "CAgilentLan" aufgerufen wird folgende Erweiterung
                  in der Konstruktor der betroffene Class als Beispiel z.B "CKlassA":

                  	m_pvWorkerThread = new QThread();
                  	m_pvAgilentWorker = new CAgilentLan(settings_l.strfuGetIP_DSO(), 500, settings_l.bofuGetSimulate());
                  	m_pvAgilentWorker->moveToThread(m_pvWorkerThread);
                  	//QThread und Worker aufräumen bei Programmende
                  	connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &QThread::deleteLater);
                  	connect(m_pvAgilentWorker, &CAgilentLan::finished, m_pvAgilentWorker, &CAgilentLan::deleteLater);
                  	
                  

                  m_pvWorkerThread und m_pvAgilentWorker sind als member Variable deklariert:

                  	CAgilentLan* m_pvAgilentWorker;
                  	QThread* m_pvWorkerThread;
                  

                  Die Frage ist wo soll ich denn:

                  m_pvWorkerThread -> start();
                  

                  aufrufen?
                  Ohne diese Aufruf funktioniert aber wenn ich die Application beende knallt, da es in eine andere Stelle
                  eine Member Variable diese class erstelle "CKlassA" und normal in der Destruktor lösche ich das wieder und genau dort knallt.
                  -->Fehlermeldung:

                  ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 478d180. Receiver '' (of type 'QNativeSocketEngine') was created in thread 47d4228", file kernel\qcoreapplication.cpp, line 541
                  
                  

                  Danke

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    Galilio
                    wrote on last edited by
                    #23

                    @J-Hilk
                    Auf eine kurze Antwort werde ich mich freuen.

                    J.HilkJ 1 Reply Last reply
                    0
                    • G Galilio

                      @J-Hilk
                      Auf eine kurze Antwort werde ich mich freuen.

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #24

                      @Galilio
                      Hi, guten Morgen,

                      ich war leider die Woche sehr beschäftigt auf Arbeit.

                      Zu deiner Frage,
                      deine Worker-Klasse wird, so wie man es auch machen soll, im Main-Thread erstellt und anschließend in dem Thread übergeben.

                      Das bedeutet aber auch das alle Objekte im Constructor die du ohne parent erstellst, z.B. der TCPSocket, werden nicht automatisch mit verschoben.
                      Also entweder alles im Worker Constructor in einer Funktion ausführen, die nach thread started aufgerufen wird, oder die Objecte ebenfalls mit moveToThread dem QThread object übergeben.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      G 1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        Galilio
                        wrote on last edited by
                        #25

                        @J-Hilk

                        danke für die Antwort.
                        Ich brauche aber wirklich deine Hilfe.
                        Egal wie ich das implementiere.
                        Ich bekomme stets diese Fehlermeldung:

                        ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 860030. Receiver '' (of type 'QNativeSocketEngine') was created in thread 490ef60", file kernel\qcoreapplication.cpp, line 541
                        

                        Ich weiss es nicht was ich denn falsch mache...................
                        Vielen Dank in voraus

                        1 Reply Last reply
                        0
                        • J.HilkJ J.Hilk

                          @Galilio
                          Hi, guten Morgen,

                          ich war leider die Woche sehr beschäftigt auf Arbeit.

                          Zu deiner Frage,
                          deine Worker-Klasse wird, so wie man es auch machen soll, im Main-Thread erstellt und anschließend in dem Thread übergeben.

                          Das bedeutet aber auch das alle Objekte im Constructor die du ohne parent erstellst, z.B. der TCPSocket, werden nicht automatisch mit verschoben.
                          Also entweder alles im Worker Constructor in einer Funktion ausführen, die nach thread started aufgerufen wird, oder die Objecte ebenfalls mit moveToThread dem QThread object übergeben.

                          G Offline
                          G Offline
                          Galilio
                          wrote on last edited by
                          #26

                          @J.Hilk

                          Hallo,

                          ich bin einfach zurück zu deinem erstellten demo ThreadProjekt, die du erstellt hast.
                          1)
                          Beim Worker class hast du wie folgende implementiert:

                          Worker::Worker(QObject *parent) : QObject(parent)
                          {
                          
                          }
                          
                          void Worker::init()
                          {
                              timer = new QTimer(this);
                              timer->setInterval(100);
                              connect(timer, &QTimer::timeout, this, &Worker::calculate);
                          }
                          

                          Hier habe ich eine Frage im bezug auf das :

                          connect(timer, &QTimer::timeout, this, &Worker::calculate);
                          

                          Hier tust folgende:
                          wird eine timeout (Signal) auftreten, dann wird das Slot calculate aufgerufen.
                          Richtig?
                          dann die restlichen Implemtierung
                          ...

                          void Worker::calculate()
                          {
                              qreal result = qPow(m_Base, m_Expo);
                              emit qThreadResult(QString::number(result) + " um "+QTime::currentTime().toString("mm:hh:ss.zzz"));
                          }
                          // einfach signal "qThreadResult(...)" emittiert
                          

                          2)
                          Bei deinem class MainWindow in der Konstruktor hast du folgende geschrieben:

                          MainWindow::MainWindow(QWidget *parent) :
                              QMainWindow(parent),
                              ui(new Ui::MainWindow)
                          {
                           .....
                              //!QThread
                              //Initalisierung des Threads und der Workerklasse
                              QThread * workerThread = new QThread();
                              Worker *workerObject = new Worker();
                              workerObject->moveToThread(workerThread);
                              connect(workerThread, &QThread::started, workerObject, &Worker::init);
                          	
                          
                              //QThread und Worker aufräumen bei Programmende
                              connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
                              connect(workerThread, &QThread::finished, workerObject, &Worker::deleteLater);
                              connect(qApp, &QApplication::aboutToQuit, workerThread, &QThread::quit);
                          
                              // Interaktion mit der Benutzeroberfläche
                              connect(ui->btnQThread, &QPushButton::clicked,                                  workerObject, &Worker::start);
                              connect(workerObject,   &Worker::qThreadResult,                                 ui->lblResult,&QLabel::setText);
                              connect(ui->dSpinBase,  QOverload<double>::of(&QDoubleSpinBox::valueChanged),   workerObject, &Worker::newBase);
                              connect(ui->dSpinExp,   QOverload<double>::of(&QDoubleSpinBox::valueChanged),   workerObject, &Worker::newExponent);
                          
                              workerThread->start();
                          }
                          

                          Mich interessiert das:

                          connect(workerThread, &QThread::started, workerObject, &Worker::init);
                          // hier baut eine Verbindung zwischen das Signal started von QThread Object und das Slot von Worker Object
                          //also solange der QThread noch lebt wird immer der slot init aufgerufen, der wiederum das Slot calculate aufruft.
                          

                          Richtig?

                          10000 danke in voraus und Sorry

                          J.HilkJ 1 Reply Last reply
                          0
                          • G Galilio

                            @J.Hilk

                            Hallo,

                            ich bin einfach zurück zu deinem erstellten demo ThreadProjekt, die du erstellt hast.
                            1)
                            Beim Worker class hast du wie folgende implementiert:

                            Worker::Worker(QObject *parent) : QObject(parent)
                            {
                            
                            }
                            
                            void Worker::init()
                            {
                                timer = new QTimer(this);
                                timer->setInterval(100);
                                connect(timer, &QTimer::timeout, this, &Worker::calculate);
                            }
                            

                            Hier habe ich eine Frage im bezug auf das :

                            connect(timer, &QTimer::timeout, this, &Worker::calculate);
                            

                            Hier tust folgende:
                            wird eine timeout (Signal) auftreten, dann wird das Slot calculate aufgerufen.
                            Richtig?
                            dann die restlichen Implemtierung
                            ...

                            void Worker::calculate()
                            {
                                qreal result = qPow(m_Base, m_Expo);
                                emit qThreadResult(QString::number(result) + " um "+QTime::currentTime().toString("mm:hh:ss.zzz"));
                            }
                            // einfach signal "qThreadResult(...)" emittiert
                            

                            2)
                            Bei deinem class MainWindow in der Konstruktor hast du folgende geschrieben:

                            MainWindow::MainWindow(QWidget *parent) :
                                QMainWindow(parent),
                                ui(new Ui::MainWindow)
                            {
                             .....
                                //!QThread
                                //Initalisierung des Threads und der Workerklasse
                                QThread * workerThread = new QThread();
                                Worker *workerObject = new Worker();
                                workerObject->moveToThread(workerThread);
                                connect(workerThread, &QThread::started, workerObject, &Worker::init);
                            	
                            
                                //QThread und Worker aufräumen bei Programmende
                                connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
                                connect(workerThread, &QThread::finished, workerObject, &Worker::deleteLater);
                                connect(qApp, &QApplication::aboutToQuit, workerThread, &QThread::quit);
                            
                                // Interaktion mit der Benutzeroberfläche
                                connect(ui->btnQThread, &QPushButton::clicked,                                  workerObject, &Worker::start);
                                connect(workerObject,   &Worker::qThreadResult,                                 ui->lblResult,&QLabel::setText);
                                connect(ui->dSpinBase,  QOverload<double>::of(&QDoubleSpinBox::valueChanged),   workerObject, &Worker::newBase);
                                connect(ui->dSpinExp,   QOverload<double>::of(&QDoubleSpinBox::valueChanged),   workerObject, &Worker::newExponent);
                            
                                workerThread->start();
                            }
                            

                            Mich interessiert das:

                            connect(workerThread, &QThread::started, workerObject, &Worker::init);
                            // hier baut eine Verbindung zwischen das Signal started von QThread Object und das Slot von Worker Object
                            //also solange der QThread noch lebt wird immer der slot init aufgerufen, der wiederum das Slot calculate aufruft.
                            

                            Richtig?

                            10000 danke in voraus und Sorry

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #27

                            Guten Morgen @Galilio ,

                            zu deinem letzten post:

                            das Signal QThread::started wird nur dann ausgelöst wenn QThread bereit ist die EventLoop zu starten, also kurz bevor (intern) exec in run gecalled wird.

                            Das passiert eigendlich nur einmal in der Lebenszeit des Threads.

                            Ist nen Privates Signal, d.h. nur das QThread Object kann es auslösen, aber man kann sich von außerhalb an das Signal hängen, mit nem connect. Klick hier zum nachlesen

                            Und das ist auch was im Beispiel passiert. Weil connect(workerThread, &QThread::started, workerObject, &Worker::init);eine Qt::Queuedconnection ist, wird init auf jedenfall erst dann ausgeführt, wenn die QThread eventloop läuft.

                            Der Connecttyp ist nicht expliciet definiert -> Auto als standart -> Queuedconnection weil Threadübergreifend.

                            Zu dem post davor,
                            sieht so aus, als ob die Objecte im Constructor im original Thread erstellst und nicht mit verschiebst. Aber ohne Code ist da schwer was zu sagen, der Stacktrace sollte dir aufschluß darüber geben in welcher Zeile das passiert. Programm mal in Debug starten und gucken :-)


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            G 2 Replies Last reply
                            0
                            • J.HilkJ J.Hilk

                              Guten Morgen @Galilio ,

                              zu deinem letzten post:

                              das Signal QThread::started wird nur dann ausgelöst wenn QThread bereit ist die EventLoop zu starten, also kurz bevor (intern) exec in run gecalled wird.

                              Das passiert eigendlich nur einmal in der Lebenszeit des Threads.

                              Ist nen Privates Signal, d.h. nur das QThread Object kann es auslösen, aber man kann sich von außerhalb an das Signal hängen, mit nem connect. Klick hier zum nachlesen

                              Und das ist auch was im Beispiel passiert. Weil connect(workerThread, &QThread::started, workerObject, &Worker::init);eine Qt::Queuedconnection ist, wird init auf jedenfall erst dann ausgeführt, wenn die QThread eventloop läuft.

                              Der Connecttyp ist nicht expliciet definiert -> Auto als standart -> Queuedconnection weil Threadübergreifend.

                              Zu dem post davor,
                              sieht so aus, als ob die Objecte im Constructor im original Thread erstellst und nicht mit verschiebst. Aber ohne Code ist da schwer was zu sagen, der Stacktrace sollte dir aufschluß darüber geben in welcher Zeile das passiert. Programm mal in Debug starten und gucken :-)

                              G Offline
                              G Offline
                              Galilio
                              wrote on last edited by Galilio
                              #28

                              @J.Hilk

                              Problem tritt wenn die Application verlassen wird.

                              Beim Verlassen der application wird der destrctor der CAgilentLan aufgerufen, der so aussieht:

                              CAgilentLan::~CAgilentLan()
                              {
                              	this->Close(GetiTimeOutClose());
                              
                              	if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK)
                              	{
                              		throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error"));
                              	}
                              }
                              

                              die close Methode sieht wie folgende aus:

                              bool CAgilentLan::Close(const int iTimeout_p)
                              {
                              	bool boRet_l = true;
                              
                              	if (this->Execute("CloseConnection", 500, iTimeout_p, 1000) != enRspOK)
                              	{
                              		throw(QString("Error AgilentLan.CPP/Close Connection error"));
                              	}
                              	
                              	if (GetboDebug())
                              	{
                              		throw(QString("Tcp Socket is closed"));
                              	}
                              
                              	return boRet_l;
                              }
                              

                              und genau gesagt hier knallt:

                              	GetTcpSocket()->disconnectFromHost();
                              

                              Das Object "GetTcpSocket()" ist nicht gleich NULL, sonst hätte ich einen ganze andere Fehlermeldung.

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                Galilio
                                wrote on last edited by Galilio
                                #29

                                Guten morgen zusammen
                                Problem wurde gelöst.
                                ich habe es immer den falschen Thread benutzt und dazu versuche ich ihm zu löschen.
                                danke
                                @J-Hilk

                                1 Reply Last reply
                                1
                                • J.HilkJ J.Hilk

                                  Guten Morgen @Galilio ,

                                  zu deinem letzten post:

                                  das Signal QThread::started wird nur dann ausgelöst wenn QThread bereit ist die EventLoop zu starten, also kurz bevor (intern) exec in run gecalled wird.

                                  Das passiert eigendlich nur einmal in der Lebenszeit des Threads.

                                  Ist nen Privates Signal, d.h. nur das QThread Object kann es auslösen, aber man kann sich von außerhalb an das Signal hängen, mit nem connect. Klick hier zum nachlesen

                                  Und das ist auch was im Beispiel passiert. Weil connect(workerThread, &QThread::started, workerObject, &Worker::init);eine Qt::Queuedconnection ist, wird init auf jedenfall erst dann ausgeführt, wenn die QThread eventloop läuft.

                                  Der Connecttyp ist nicht expliciet definiert -> Auto als standart -> Queuedconnection weil Threadübergreifend.

                                  Zu dem post davor,
                                  sieht so aus, als ob die Objecte im Constructor im original Thread erstellst und nicht mit verschiebst. Aber ohne Code ist da schwer was zu sagen, der Stacktrace sollte dir aufschluß darüber geben in welcher Zeile das passiert. Programm mal in Debug starten und gucken :-)

                                  G Offline
                                  G Offline
                                  Galilio
                                  wrote on last edited by
                                  #30
                                  This post is deleted!
                                  J.HilkJ 1 Reply Last reply
                                  0
                                  • G Galilio

                                    This post is deleted!

                                    J.HilkJ Offline
                                    J.HilkJ Offline
                                    J.Hilk
                                    Moderators
                                    wrote on last edited by
                                    #31

                                    @Galilio
                                    hi,

                                    Warum bestehst du eigentlich auf einer Synchronen TCPSocket Lösung? Wenn möglich sollte man immer die Asynchronen Funktionen nehmen.

                                    Das gesagt, waitForDisconnected hat in der docu den Beisatz

                                    Note: This function may fail randomly on Windows. Consider using the event loop and the disconnected() signal if your software will run on Windows.
                                    

                                    Also besondere Vorsicht die man hier walten lassen sollte.

                                    if ((GetTcpSocket()->state() == QAbstractSocket::UnconnectedState) || (GetTcpSocket()->waitForDisconnected(GetTimeOut())))
                                    

                                    ist an sich nicht falsch, der erste Parameter wird immer zuerst geprüft, und falls true, wird der Rest des IF-Statements ignoriert.
                                    Ist aber trotzdem eine blockierende Funktion und wird deinen Thread für bis zu 3 Sekunden, der default timeout, freezen.

                                    Ich würde es etwas anders lösen, und zwar über das Signal stateChanged vom TcpSocket

                                    connect(tcpSocket, &QTcpSocket::stateChanged, this, [=](QAbstractSocket::SocketState socketState{
                                        if(socketState == ConnectedState)
                                           emit SocketConnected();
                                        if(socketState == UnconnectedState)
                                           emit SocketDisconnected();
                                    });
                                    

                                    einen Timeout kannst du dir ganz leicht selbst machen mit einem QTimer

                                    void disconnectMySocket(){
                                       tcpSocket->disconnectFromHost();
                                       QTimer::singleShot(3000, this, &mySocketClass::checkDisconnected);
                                    }
                                    
                                    void checkDisconnected(){
                                       if(tcpSocket->state != UnconnectedState){
                                       //Error Handling
                                       }
                                    }
                                    

                                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                    Q: What's that?
                                    A: It's blue light.
                                    Q: What does it do?
                                    A: It turns blue.

                                    G 2 Replies Last reply
                                    1
                                    • J.HilkJ J.Hilk

                                      @Galilio
                                      hi,

                                      Warum bestehst du eigentlich auf einer Synchronen TCPSocket Lösung? Wenn möglich sollte man immer die Asynchronen Funktionen nehmen.

                                      Das gesagt, waitForDisconnected hat in der docu den Beisatz

                                      Note: This function may fail randomly on Windows. Consider using the event loop and the disconnected() signal if your software will run on Windows.
                                      

                                      Also besondere Vorsicht die man hier walten lassen sollte.

                                      if ((GetTcpSocket()->state() == QAbstractSocket::UnconnectedState) || (GetTcpSocket()->waitForDisconnected(GetTimeOut())))
                                      

                                      ist an sich nicht falsch, der erste Parameter wird immer zuerst geprüft, und falls true, wird der Rest des IF-Statements ignoriert.
                                      Ist aber trotzdem eine blockierende Funktion und wird deinen Thread für bis zu 3 Sekunden, der default timeout, freezen.

                                      Ich würde es etwas anders lösen, und zwar über das Signal stateChanged vom TcpSocket

                                      connect(tcpSocket, &QTcpSocket::stateChanged, this, [=](QAbstractSocket::SocketState socketState{
                                          if(socketState == ConnectedState)
                                             emit SocketConnected();
                                          if(socketState == UnconnectedState)
                                             emit SocketDisconnected();
                                      });
                                      

                                      einen Timeout kannst du dir ganz leicht selbst machen mit einem QTimer

                                      void disconnectMySocket(){
                                         tcpSocket->disconnectFromHost();
                                         QTimer::singleShot(3000, this, &mySocketClass::checkDisconnected);
                                      }
                                      
                                      void checkDisconnected(){
                                         if(tcpSocket->state != UnconnectedState){
                                         //Error Handling
                                         }
                                      }
                                      
                                      G Offline
                                      G Offline
                                      Galilio
                                      wrote on last edited by
                                      #32

                                      @J.Hilk
                                      vielen dank
                                      Dein tipps sind super

                                      1 Reply Last reply
                                      0
                                      • J.HilkJ J.Hilk

                                        @Galilio
                                        hi,

                                        Warum bestehst du eigentlich auf einer Synchronen TCPSocket Lösung? Wenn möglich sollte man immer die Asynchronen Funktionen nehmen.

                                        Das gesagt, waitForDisconnected hat in der docu den Beisatz

                                        Note: This function may fail randomly on Windows. Consider using the event loop and the disconnected() signal if your software will run on Windows.
                                        

                                        Also besondere Vorsicht die man hier walten lassen sollte.

                                        if ((GetTcpSocket()->state() == QAbstractSocket::UnconnectedState) || (GetTcpSocket()->waitForDisconnected(GetTimeOut())))
                                        

                                        ist an sich nicht falsch, der erste Parameter wird immer zuerst geprüft, und falls true, wird der Rest des IF-Statements ignoriert.
                                        Ist aber trotzdem eine blockierende Funktion und wird deinen Thread für bis zu 3 Sekunden, der default timeout, freezen.

                                        Ich würde es etwas anders lösen, und zwar über das Signal stateChanged vom TcpSocket

                                        connect(tcpSocket, &QTcpSocket::stateChanged, this, [=](QAbstractSocket::SocketState socketState{
                                            if(socketState == ConnectedState)
                                               emit SocketConnected();
                                            if(socketState == UnconnectedState)
                                               emit SocketDisconnected();
                                        });
                                        

                                        einen Timeout kannst du dir ganz leicht selbst machen mit einem QTimer

                                        void disconnectMySocket(){
                                           tcpSocket->disconnectFromHost();
                                           QTimer::singleShot(3000, this, &mySocketClass::checkDisconnected);
                                        }
                                        
                                        void checkDisconnected(){
                                           if(tcpSocket->state != UnconnectedState){
                                           //Error Handling
                                           }
                                        }
                                        
                                        G Offline
                                        G Offline
                                        Galilio
                                        wrote on last edited by
                                        #33

                                        @J.Hilk
                                        Hi,

                                        Das

                                        void disconnectMySocket(){
                                           tcpSocket->disconnectFromHost();
                                           QTimer::singleShot(3000, this, &mySocketClass::checkDisconnected);
                                        }
                                        
                                        void checkDisconnected(){
                                        // Diese Funktion wird aber ne aufgerufen
                                           if(tcpSocket->state != UnconnectedState){
                                           //Error Handling
                                           }
                                        }
                                        

                                        wird aber ne erreicht.

                                        J.HilkJ 1 Reply Last reply
                                        0
                                        • G Galilio

                                          @J.Hilk
                                          Hi,

                                          Das

                                          void disconnectMySocket(){
                                             tcpSocket->disconnectFromHost();
                                             QTimer::singleShot(3000, this, &mySocketClass::checkDisconnected);
                                          }
                                          
                                          void checkDisconnected(){
                                          // Diese Funktion wird aber ne aufgerufen
                                             if(tcpSocket->state != UnconnectedState){
                                             //Error Handling
                                             }
                                          }
                                          

                                          wird aber ne erreicht.

                                          J.HilkJ Offline
                                          J.HilkJ Offline
                                          J.Hilk
                                          Moderators
                                          wrote on last edited by
                                          #34

                                          @Galilio
                                          mit ziehmlicher sicherheit wird das aufgerufen x), Fehlermeldungen falls vorhanden immer mit posten.

                                          Ich hab das so vereinfacht geschrieben wie möglich, das muss an dein Programm angepasst werden.

                                          wenn die den Slot vermeiden möchtest kann man das auch in ein Lamda stecken.
                                          Das wird auf jeden Fall aufgerufen, oder zumindest wird der compiler abbrechen mit einer Fehlermeldung:

                                          void disconnectMySocket(){
                                             tcpSocket->disconnectFromHost();
                                             QTimer::singleShot(3000, this, [=]{
                                                 if(tcpSocket->state != UnconnectedState){
                                                     //Error Handling
                                                 }
                                             });
                                          }
                                          

                                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                          Q: What's that?
                                          A: It's blue light.
                                          Q: What does it do?
                                          A: It turns blue.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved