Thread-Beispiel

  • Formular-Klasse
  • form.cpp
  • #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
        // Suspended Thread erstellen, d.h. der Thread läuft erstmal nicht los
        pAnzeigeThread = new TTestThread(true, Edit3);
        pAnzeigeThread->Priority = tpIdle; // Idle-Thread erstellen
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
    
        pAnzeigeThread->Terminate(); // Thread killen
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        // Wenn der Thread nicht angehalten wurde, dann starten
        if (pAnzeigeThread->Suspended)
        {
            pAnzeigeThread->Resume();
        }
        else
        {
            pAnzeigeThread->Suspend(); // sonst anhalten
        }
    }
    
  • form.h
  • #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    #include "UThread.h"
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    
        __published: // Von der IDE verwaltete Komponenten
    
            TEdit *Edit3;
            TButton *Button1;
            void __fastcall FormDestroy(TObject *Sender);
            void __fastcall Button1Click(TObject *Sender);
    
        private: // Anwender-Deklarationen
    
            TTestThread *pAnzeigeThread; // Zeiger auf den Thread deklarieren
    
        public: // Anwender-Deklarationen
    
            __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    
  • Thread Klasse
  • Thread.cpp
  • #include <vcl.h>
    #pragma hdrstop
    
    #include "UThread.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    __fastcall TTestThread::TTestThread(bool CreateSuspended, TEdit *Edit) : TThread(CreateSuspended)
    {
        FreeOnTerminate = true; // wenn der Thread gekillt wird, dann gleich entfernen
        Ausgabe = Edit; // die Ausgabe erfolgt in einem Edit-Feld, das auf der Mainform liegt
        uiCount = 0;
    }
    //---------------------------------------------------------------------------
    // Hier steht der Code der vom Thread ausgeführt wird
    //---------------------------------------------------------------------------
    void __fastcall TTestThread::Execute()
    {
        // solange der Thread nicht gekillt wurde
        while (!Terminated)
        {
            Ausgabe->Text = IntToStr(uiCount);
            if (uiCount < 100000) uiCount++;
            else uiCount = 0;
        }
    }
    &#91;/sourcecode&#93;
    	<li>Thread.h</li>
    [sourcecode language="cpp"]
    #ifndef UThreadH
    #define UThreadH
    //---------------------------------------------------------------------------
    #include <Classes.hpp->
    //---------------------------------------------------------------------------
    class TTestThread : public TThread
    { 
        private:
            unsigned int uiCount;
        protected:
            TEdit *Ausgabe; // Zeiger auf das Ausgabe-Edit-Feld
            void __fastcall Execute();
        public:
            __fastcall TTestThread(bool CreateSuspended, TEdit *Edit);
    };
    //---------------------------------------------------------------------------
    #endif
    

Grundlagen zu Threads

  • Kern des Threads ist die Execute-Methode, diese wird nach Starten des Threads abgearbeitet
  • void __fastcall MyThread::Execute()
    {
         // Hier steht der Code der vom Thread abgearbeitet wird 
    } 
    
  • Alle Methoden, die im Thread aufgerufen werden und auf VCL-Elemente zugreifen, sollten der Methode Synchronize übergeben werden. Dies ist sehr wichtig, damit alle Zugriffe etc. synchron mit dem Hauptthread der VCL verlaufen:
  • Synchronize(DieMethode);
    
  • man kann im Konstruktor angeben, ob der Thread sofort nach dem Erzeugen des Objektes losläuft, oder ob der Thread zunächst ruht:
  • MyThread = new TThread(true); // Thread ist erstmal stillgelegt (suspended = true)
    
    oder
    
    MyThread = new TThread(false); // Thread läuft sofort los
    
  • Thread-Priorität festlegen:
  • MyThread->Priority = Prioritäts-Stufe // Prioritäts-Stufe kann sein tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical
    
  • Thread Starten/Anhalten:
  • MyThread->Resume(); // startet den Thread
    
    MyThread->Suspend(); // hält den Thread an
    
  • Thread beenden:
  • MyThread->Terminate();
    
  • will man eine gewisse Routine beim Beenden des Threads durchlaufen, muss man diese dem OnTerminate-Ereignis des Threads zuweisen:
  • MyThread->OnTerminate = ThreadOnTerminate; // dem Thread die Methode ThreadOnTerminate zu, die ausgeführt wird, sobald das Ereignis OnTerminate eintritt
    
  • Thread nach dem Beenden gleich freigeben:
  • FreeOnTerminate = true; // im Konstruktor des Threads oder nach der Erzeugung kann man angeben ob der Thread bei Terminierung freigegeben werden soll