Announcement

Collapse
No announcement yet.

threads und events

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

  • threads und events

    Hallo,<br>
    ich möchte aus meiner Hauptanwendung heraus (einer Konsolenanwendung) einen Thread erzeugen und starten. Danach arbeitet die Hauptanwendung normal weiter, ohne jemals auf die Beendigung des Threads zu warten, d.h. der Thread macht seinen Job und beendet sich schließlich selbst.

    Der Thread soll (in dem Hier gewählten Beispiel) einen Timer starten, der alle 100ms ein Event auslöst. Jedes mal wenn das Event ausgelöst wird, soll eine Ausgabe auf der Konsole gemacht werden.

    Mein Problem bei der ganzen Sache ist, dass ich es nicht hinbekomme, dass der Thread das Event mitbekommt bzw. die Prozedur zur Behandlung des Events aufgerufen wird.

    Ich weiß nicht mehr weiter. Vielen Dank für die Hilfe!
    Veit

    <pre>
    <i>//MyThread.pas</i>
    <b>unit</b> MyThread;
    <br>
    <b>interface</b>
    <br>
    <b>uses</b>
    Forms,
    SysUtils,
    ExtCtrls,
    Classes;
    <br>
    <b>type</b>
    TMethodPointer = record
    pMethod: Pointer;
    pObject: TObject;
    <b> end;</b>
    <br>
    TMyThread = <b>class</b>(TThread)
    <b>constructor</b> Create( CreateSuspended: Boolean );
    <b>procedure</b> NotifyEvent(Sender: Tobject);
    <b> private</b>
    p : TMethodPointer;
    t : TTimer;
    <b> protected</b>
    <b>procedure</b> Execute; <b>override</b>;
    <b> end</b>;
    <br>
    <b>implementation</b>
    <br>
    <b>constructor</b> TMyThread.Create( CreateSuspended: Boolean );
    <b>begin</b>
    <b>inherited</b> Create( CreateSuspended );
    p.pMethod := @TMyThread.NotifyEvent;
    p.pObject := <b>nil</b>;
    t := TTimer.Create(<b>nil</b>);
    t.Enabled := false; <i>//deaktiviert timer </i>
    t.Interval := 100; <i>//alle 100ms ein OnTimerEvent</i>
    t.OnTimer := TNotifyEvent(p); <i>//Prozedur dem OnTimerEvent zuordnen</i>
    <b>end</b>;
    <br>
    <b>procedure</b> TMyThread.NotifyEvent(Sender: TObject);
    <b>begin</b>
    writeln('Ja, event behandelt');
    SysUtils.Beep;
    <b>end</b>;
    <br>
    <b>procedure</b> TMyThread.Execute;
    <b>var</b>
    i : integer;
    <b>begin</b>
    t.Enabled := true; <i>// aktiviert den Timer</i>
    <b>for</b> i := 1 <b>to</b> 10 do <b>begin</b>
    sleep(50);
    writeln('warte auf event');
    Application.ProcessMessages; <i>//eventliste abarbeiten :-(scheint nicht zu wirken)</i>
    <b> end</b>;
    t.Enabled := false; <i>// deaktiviert den Timer</i>
    <b>end</b>;
    <br>
    <b>end</b>.
    </pre>

  • #2
    Hast Du Dir mal die Hilfe zum Thread durchgelesen? Ganz so einfach geht das nicht. Du musst mit Synchronize arbeiten, wenn Du auf etwas zugreifen willst, was im Hauptthread liegt. Und Sound und Ausgabe zählen sicher dazu.<p>
    Schöne Grüße, Mario Noac
    Schöne Grüße, Mario

    Comment


    • #3
      Hmm, das verstehe ich noch nicht.
      Bei dem Code, den ich geschickt habe, gibt der Thread auf der Konsole schon etwas aus.
      und zwar 10 mal:

      warte auf event

      und niemals wird ausgegeben:

      Ja, Event behandelt

      Oder benötige ich synchonize, damit das Event auch wirklich ausgelöst wird

      Comment


      • #4
        Hmm, also Synchronize brauchst Du eigentlich, um auf Thread-Fremde Sache zuzugreifen, also meiner Auffassung auch die Konsolenausgabe. Aber scheinbar ist das nicht problematisch.<p>
        Ich würde nun zwei Sachen testen. Einmal erscheint mit die Zuweisung auf OnTimer suspect. Kannst Du mal in der Anwendung testen, ob das auch unter normalen Umständen funktioniert?<p>
        Ansonsten könnte ich mir vorstellen, dass ein Timer in einem Thread generell nicht eingesetzt werden kann. Wenn ich mir den Source von Borland zum Timer anschaue, so ist mir dieser nicht direkt einleuchtend. Es könnte also durchaus sein, dass die Message wm_Timer, welche genutzt wird, Deinen Thread gar nicht erreicht, sondern im Hauptfenster versumpft. Was spricht denn gegen eine simple Schleife, mit einem Sleep aufgebohrt. Du hast ja einen eigenen Thread, blockierst Dir damit also Deinen Hauptanwendung nicht?<p>
        Schöne Grüße, Mario Noac
        Schöne Grüße, Mario

        Comment


        • #5
          Sollte eingentlich funktionieren. Hab' das eben mal im BCB nachgebastelt: Läuft einwandfrei. Kann das Sleep in der Schleife Schuld siein?

          Was passiert wenn Du diese Zeilen wegläßt:
          <PRE>
          for i := 1 to 10 do begin
          sleep(50);
          writeln('warte auf event');
          Application.ProcessMessages; //eventliste abarbeiten :-(scheint nicht zu wirken)
          end;
          </PRE>

          Mein (zugeben simpler) TestThread:
          Header:
          <PRE>
          class TestThread : public TThread
          {
          private:
          TTimer* TestTimer;
          protected:
          void __fastcall Execute();
          public:
          __fastcall TestThread(bool CreateSuspended);
          __fastcall ~TestThread();
          void __fastcall TimerEvent(TObject* Sender);
          };
          </PRE>
          CPP:
          <PRE>
          __fastcall TestThread::TestThread(bool CreateSuspended)
          : TThread(CreateSuspended)
          {
          TestTimer = new TTimer(NULL);
          TestTimer->OnTimer = TimerEvent;
          }
          //---------------------------------------------------------------------------
          __fastcall TestThread::~TestThread()
          {
          delete TestTimer;
          }
          //---------------------------------------------------------------------------
          void __fastcall TestThread::Execute()
          {
          TestTimer->Interval = 1000;
          TestTimer->Enabled = true;
          }
          //---------------------------------------------------------------------------
          void __fastcall TestThread::TimerEvent(TObject* Sender)
          {
          TestTimer->Enabled = false;
          ShowMessage("Timer Event!");
          TestTimer->Enabled = true;
          }
          </PRE>

          Grüße Joche

          Comment

          Working...
          X