Instanziierung TTimer in Execute von TThread



  • Hallo Leute,

    ich habe im Header eine Membervariable vom Typ TTimer* mAliveTimer deklariert.
    Will ich den Timer in der Methode Execute() instanziieren, läuft dieser Timer nie ab, also OnTimer wird nicht ausgelöst.
    Instanziiere ich den Timer im Konstruktor arbeitet der Timer fehlerfrei.

    Kennt jemand dieses Phänomen und hat eine Erklärung dafür?



  • etwas Quellcode wäre nicht schlecht, ansonsten isses das berühmte Glaskugelraten ... aber von Threadunverträglichkeit hab ich so noch nichts bemerkt als ich mal sowas gemacht habe.



  • so funktiniert es:

    __fastcall NodeProxy::NodeProxy(...
    {
    ...
        Priority = tpNormal;
        mAliveTimer = new TTimer(NULL);
    }
    
    void __fastcall NodeProxy::Execute()
    {
    ...
        mAliveTimer->Interval = 5000;
        mAliveTimer->Enabled = true;
        mAliveTimer->OnTimer = &timeoutAlive;
    ...
    }
    

    so nicht:

    void __fastcall NodeProxy::Execute()
    {
    ...
        mAliveTimer = new TTimer(NULL);
        mAliveTimer->Interval = 5000;
        mAliveTimer->Enabled = true;
        mAliveTimer->OnTimer = &timeoutAlive;
    ...
    }
    


  • Kernel386 schrieb:

    mAliveTimer->OnTimer = &timeoutAlive;
    

    TTimer::OnTimer ist ein Closure, d.h. ein Methodenzeiger, der sowohl Objekt als auch Methode speichert. Dementsprechend mußt du ihn zuweisen:

    mAliveTimer->OnTimer = this->timeoutAlive;
    


  • huh (O_o) ich hab den "this" immer pauschal dazugeschrieben ... fügt der konstruktor den objekt link denn automatisch mit ein im gegensatz zu einer aufgerufenen methode ?



  • Nicht daß ich wüßte. Ich weiß nicht, weshalb es dort funktioniert hat und weshalb der Compiler obige Syntax akzeptiert.

    Funktioniert es jetzt?



  • Hallo audacia,

    ich habe deine vorgeschlagene Änderung durchgeführt. Sorry mein Fehler, war mir gar nicht aufgefallen.
    Wir haben mal eine Klasse geschrieben, welche es uns ermöglicht TTimer auch in ganz normalen Klassen zu verwenden. Daher war das & und noch übrig geblieben. Die hatte ich erst verwendet.
    Zum Thema zurück. Sobald ich

    mAliveTimer = new TTimer(NULL);
    

    nach Execute verpflanze läuft der Timer nicht mehr, auch mit der Änderung.



  • aber du instantiierst nicht zyklisch mit deiner execute schleife neu oder?
    ih frag nur weil dein code ziemlich viel auskommentiert hat



  • Was spricht denn dagegen, die Instantiierung des Timers nur einmal im Konstruktor vorzunehmen? Die Eigenschaftszuweisungen würde ich auch schon nur einmalig im Konstruktor vornehmen (bis auf Enabled).
    Interessant wäre ansonsten wirklich die Schleife um den Timer in Execute()?



  • Hallo Ceos,
    nein ich instanziere nicht zyklisch. Es geschieht alles vor der while-Schleife.

    Hallo Th,
    es spricht nichts dagegen den Timer im Konstruktor zu instanzieren. Ich fand es nur seltsam, das das in Execute nicht geht.
    Ich dachte, vielleicht hat einer der schlauen Köpfe hier im Forum eine eine Erklärung dafür!



  • kurze Frage, wie sieht bei dir die Funktion timeoutAlive aus? Der enthaltene Code interessiert mich nicht, nur die Funktion an sich.

    greetz KN4CK3R


Anmelden zum Antworten