Announcement

Collapse
No announcement yet.

Thread starten, beenden und entsorgen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Thread starten, beenden und entsorgen

    Hallo,

    ich möchte einen Thread starten (klappt einwandfrei, auch der Code in
    TEngineCtl::Execute()). Ich möchte 2 Buttons: Starten und Beenden des Threads.
    Auf Start und Beenden kann ich je ein paarmal klicken dann stürtzt der
    Hauptthread (Form1) ab.

    Klar ist, dass ich nicht >1x "TestRun = new TEngineCtl(false);" ausführen
    sollte s.u. aber selbst wenn ich die Zeile durch TestRun->Resume ersetze
    und im FormCreate:
    ----------------------------------------------
    TestRun = new TEngineCtl(false);
    TestRun->Suspend();
    ----------------------------------------------
    eintrage stürzt die Anwendung nach mehrfachem Start/Beenden klicken ab.

    Warum funktioniert delete TestRun nicht? :
    [C++ Fehler] Main.cpp(200): E2166 Zugriff auf Destruktor für 'TEngineCtl' nicht möglich.

    Der Destructor existiert:
    _fastcall TEngineCtl::~TEngineCtl() {
    delete perf0;
    }

    Leider funktionieren die Links hier im Forum mit Tips mit dem Umgang mit Threads nicht mehr und eine verfnünftige Lösung konnte ich bisher nicht
    ergooglen.

    WIE startet, beendet und entsorgt man einen Thread ordentlich?

    Hier die Buttons:
    -----------------------------------------------------------------------
    void __fastcall TForm1::StartClick(TObject *Sender)
    {
    TestRun = new TEngineCtl(false);
    Start->Enabled=false;
    Button3->Enabled=true;
    }


    void __fastcall TForm1::BeendenClick(TObject *Sender)
    {
    TestRun->Suspend();
    TestRun->Terminate(); // Thread beenden
    // delete TestRun; // Warum funkt das nicht
    Start->Enabled=true; // Startbutton aktivieren
    Button3->Enabled=false; // Abbrechenbutton deaktivieren
    }

  • #2
    // delete TestRun; // Warum funkt das nicht -> weil er sich selber wegräumt

    Starten
    Entweder durch den Konstruktor des Thread oder mit Resume

    Anhalten
    Mit Suspend

    Beenden
    Terminate

    Die Aufrufe von Resume & Suspend sind kumulativ. D.h. zweimal gestoppt mit Suspend erfordert auch zweimal Resume damit er wieder läuft.

    Terminate zum beenden des Threads



    Das hier

    TestRun = new TEngineCtl(false);

    in STARTCLICK erscheint nicht sinnvoll. Damit wird dann immer einer neuer Thread erzeugt nicht etwa ein vorhandener gestartet.

    Einmal den Thread erzeugen mit new. Dabei je nach Anforderung das Ding gleich laufen lassen oder nicht. Wenn nicht, dann mit Resume starten. Anhalten mit Suspend. Kein erneutes new in diesem Vorgang
    Christian

    Comment


    • #3
      Mit ..->Resume() im Start- und ..->Suspend im Beenden Button funktioniet
      das. Der code im ::Execute() läuft dann eben einfach weiter mit all den
      Variablenwerten die er zum Zeitpunkt des Suspend hat. Also muss ich
      jetzt noch eine public-function schreiben, die die Variablen zurücksetzt!?
      Einfacher und logischer wäre das Löschen des Objektes -> "delete TestRun" gesesen. "Objekte erst anlegen wenn sie benötigt werden" steht in meinem
      Lehrbuch.

      Comment


      • #4
        Der code im ::Execute() läuft dann eben einfach weiter mit all den
        Variablenwerten die er zum Zeitpunkt des Suspend hat.
        Wenn du Suspend machst läuft der Thread nicht weiter.
        Christian

        Comment


        • #5
          ich starte jetzt den Thread mit einem Start-Button:
          ----------------------------------------------------------------
          if (Start->Caption == "Start") {
          Start->Caption = "Abbrechen";
          TestRun = new TEngineCtl(false);
          Timer2->Enabled=false;
          } else {
          Start->Caption = "Start";
          Timer2->Enabled=true;
          TestRun->Terminate();
          }
          -------thread->Execute()-------------------------------------
          while (!this->Terminated )
          ...
          ...
          ------------------------------------------------------------------
          den nachdem Terminate(); ausgeführt wurde kann gleich wieder ein
          neues Objekt "TestRun = new TEngineCtl(false);" erzeugt werden und
          die Variablen im Execute() vor der While-Schleife werden somit neu initialisiert.
          Wie es aussieht funktioniert es so. Falls noch jemand verbesserungsvorschl. oder Kritik hat...

          Comment

          Working...
          X