Probleme mit TThread - bei erneutem Start wird Execute nur einmal ausgeführt



  • Hi

    Ich habe eine normale Form, und ein TThread-Objekt.
    Klicke ich in der Form auf einen Button, wird das TThread-Objekt per new mit CreateSuspend=false initialisiert.

    m_Rod4Handler ist ein TThread-Objekt.

    try
         {
    	  m_Rod4Handler=new Rod4Handler(false);
         }
         catch(Exception*  e)
         {
    	MessageBox(this->ClientHandle,e->Message.c_str(),"Fehler",MB_OK);
    	this->Close();
         }
         Timer1->Enabled=true;
    

    In der Execute-Methode wird zuerst eine externe Dll geladen, einige initialisierungen gemacht, und dann wird in eine while schleife übergegangen:

    void __fastcall Rod4Handler::Execute()
    {
    	  //erstmal initialisieren
    	  //dll dynamisch laden
    
    	  if(m_CanInit)
    	  {
    	   //zeugs für rauschunterdrückung initialisieren
    	   m_Bilder=new TMessung[m_AnzBilderRauschunterdrueckung];
    	   for (int counter=0; counter<m_AnzBilderRauschunterdrueckung; counter++)
    	   {
    		m_Bilder[counter].sPunkte=NULL;
    	   }
    
    	   //rod4 initialisierem
    	   InitRod4();
    	   LoadNullScan();
    	   m_CanInit=false;
    	  }
    	  m_aktStatus="Threadrunning";
    
    	  while(!this->Terminated)
    	  {
    	   //hauptschleife, die immerwieder durchlaufen wird
    	   m_aktStatus="Hauptschleife";
    	   if(m_aktBildStatus==STATUS_MAKENEWBILD)
    	   {
    		//ein rauschfreies bild, aus den gesammelten erstellen
    		m_aktStatus="Neues bild wird erstellt.";
    		CreateRauschfreiesBild();
    		m_aktBildStatus=STATUS_NOTHING;
    	   }
    	  }
    
    	 // ReleaseRod4();
    	  m_aktStatus="Erfolgreich Released";
    }
    

    Zum beenden per Knopfdruck wird wieder ein Button in der Form gedrückt:

    //Timer1->Enabled=false;
     m_Rod4Handler->StopThread();
     Label1->Caption="Alles freigegeben";
    
     delete m_Rod4Handler;
    

    Code zu Stop-Thread:

    if(m_CanInit==false)
    	ReleaseRod4();
     this->Terminate();
     m_ThreadRunning=false;
     m_CanGetBild=false;
     //alles wieder freigeben
     m_aktStatus="Beende dll";
     m_lastError=-1;
     m_AnzMesspunkte=0;
     m_PunkteAvailable=false;
     m_CanInit=true;
     m_aktBildStatus=STATUS_NOTHING;
    

    Soweit funktioniert auch alles super.

    Wenn ich jedoch den thread beendet habe, und ihn danach wieder neu starte, so wird die execute-methode nur einmal ausgeführt, und nicht mehr.

    Hatte schonmal jemand ähnliche probleme?

    Mfg

    Reinhold Fischer



  • Wie erfolgt denn der "Neustart"?

    Allgemein zum Thema Threads: Betrachte deine Execute-Methode als main. Wenn das Main durchgelaufen ist, wird das Programm beendet, ausser du verhinderst das. In deinem Fall wäre vermutlich eine Schleife angebracht, welche auf das Thread-Attribut Terminate prüft. Statt die Execute-Methode auslaufen zu lassen, lässt du als letzte Amtshandlung den Thread in den Suspendmodus gehen (TThread::Suspend). Möchtest du deinen Thread nochmals neu starten, weckst du ihn wieder auf (TThread::Resume).
    Dazu macht du noch eine Methode in deine Thread-Klasse welche Terminate heisst und etwa so aussieht:

    TMyThread::Terminate(void)
    {
        /* Die Schleife weckt den schlafenden Thread auf. Da Suspends verschachtelt 
         * werden können, kann ein mehrfacher Aufruf von Resume erforderlich sein... */
        while(this->Suspended)
        {
            this->Resume();
        }
    
        /* Aufruf der Terminate-MEthode in der Basisklasse */
        TThread::Terminate();
    }
    


  • Hi

    Also, der "Neustart" erfolgt zuerst durch freigeben der externen DLL , dann wird der Thread terminiert, und dann per delete die Instanz gelöscht.

    Daraufhin wird die Instanz per new neu initialisiert.
    Und dann die externe DLl wieder geladen.

    Mfg Reinhold fischer



  • Und dann wird der Thread nicht erneut ausgeführt? Halte ich nicht für wahrscheinlich.... Schon mal nen Breakpoint in den Start der Routine gesetzt?


Anmelden zum Antworten