timer in threads?



  • hallo, ich möchte über einen timer in einem thread ständig auf nen server zugreifen. Kann das so überhaupt funktionieren? Weil ja nix in der Execute Methode steht? Wenn nicht, wie müsste ich die Sache angehen damit was Korrektes bei raus kommt? Also compiliert wird dieser Code ohne zu zucken. Bin mir halt nicht sicher ob das mit dem Ereignishandler so funktioniert.

    hier die header vom thread

    //---------------------------------------------------------------------------
    
    #ifndef TDCOMThreadH
    #define TDCOMThreadH
    #include "ServerPrj.h"
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    //---------------------------------------------------------------------------
    class TDCOMThread : public TThread
    {
    private:
            TTimer *Timer2;
            TDataServer *DataServer1;
    protected:
            void __fastcall Execute();
            void __fastcall MyTimerEventHandler(TObject *Sender);
    public:
            __fastcall TDCOMThread(bool CreateSuspended);
    
    };
    //---------------------------------------------------------------------------
    #endif
    

    und die methoden

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "TDCOMThread.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    
    __fastcall TDCOMThread::TDCOMThread(bool CreateSuspended)
            : TThread(CreateSuspended)
    {
            FreeOnTerminate = true;
            Timer2 = new TTimer(NULL);
            DataServer1 = new TDataServer(NULL);
            Timer2->Interval = 2000;
            Timer2->Enabled = true;
            DataServer1->RemoteMachineName = localhost;
            DataServer1->AutoConnect = true;
            Timer2->OnTimer = MyTimerEventHandler()
    }
    //---------------------------------------------------------------------------
    void __fastcall TDCOMThread::Execute()
    {
       try
       {
            //---- hier den thread-code plazieren----
    
       }
       catch(...)
       {
            // festlegen, was mit exceptions geschieht
       }
    }
    //---------------------------------------------------------------------------
    void __fastcall TDCOMThread::MyTimerEventHandler(TObject *Sender)
    {
            //Zugriff auf Server
            DataServer1->GetData(0,0,NULL,0);
    }
    

    Der Server enthält auch VCL-Komponenten wie siehts da aus mit der Threadsicherheit wenn ich den Server nur in diesem Thread benutze?



  • ich denke es könnte funktionieren wenn ich den Thread mit
    CreateSuspended = true
    erzeuge.
    Im Event-Handler kann ich ja dann den schlafend erzeugten Thread aufwecken und alle Zugriffe auf den Server aus der Execute Methode aufrufen.
    Dann müsste ich aber den Thread doch wieder schlafen legen wenn der Zugriff abgeschlossen ist. Wie geht denn das nun wieder?
    Oder was meint ihr dazu?



  • Ich muss dir ehrlich sagen ich seh nicht wirklich was du genau zu erreichen versuchst... Wozu der TImer?

    Und ansonsten: Zugriffe auf die VCL müssen über Synchronize getätigt werden. Steht ja auch immer so in den neu erstellten Thread units.

    -junix



  • ich hab auf dem server bestimmte Daten die sich kontinuierlich ändern und die ich regelmässig (Timer) abfragen muss. Die empfangenen Daten will ich im Hauptthread dann auswerten und damit ich nicht warten muss bis der Server mir auf meine Anfrage endlich die Antwort geschickt hat, möchte ich die Serverkommunikation in nem Thread durchführen.
    Die VCL-Komponenten werden in der Serverklasse benutzt und ich nutze diese. Muss ich denn jetzt jede Klasse in der dann auch nur im entferntesten VCL-Klassen angesprochen werden in eine Synchronize Methode packen? Das hieße ja dann das immer wieder auf den Hauptthread gewartet werden muss. Da geht doch dann der Vorteil der Threadprogrammierung verloren weil man doch immer wieder auf irgendwelche VCL-Komponenten zugreifen muß?



  • In welchem zeitlichen Abstand soll denn auf neue Daten geprüft werden?
    Auswerten kannst Du die Daten sowieso nicht, bevor der Thread sie geliefert hat, oder übersehe ich da etwas?

    Ich würde jeweils einen neuen Thread für jede Überprüfung starten und die OnTerminate des Threads auf eine Funktion im Haupthread legen um das Ende mitzubekommen und zu erfahren wann die Daten bereit stehen. Dies läßt sich dann recht einfach synchronisieren. Sowohl die laufenden Threads, als auch die gelieferten Daten würde ich in einer TThreadList verwalten.

    Wenn es nur darum geht geänderte oder neue Dateien in einem Verzeichnis zu finden, solltest Du Dir mal die API Funktion ReadDirectoryChangesW() ansehen.



  • Während der eine Thread mit dem Holen der nächsten Daten beschäftigt ist, kann aber der andere dann schon die Daten auswerten die vorher geholt wurden.
    TThreadList ist ja von vornherein threadsicher, klar. Aber der Server ist ein TOleServer(VCL-Komponente) und müsste also in eine Synchronize Methode gebettet werden. Macht es da überhaupt Sinn den Zugriff auf den Server in nem Thread zu starten nur um dann im Thread wieder zu sagen Synchronize mit Hauptthread. Da könnt ich's doch gleich in einem Thread hintereinander ausführen oder? 😕


Anmelden zum Antworten