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?