Zitat von
mymuschy:
@unwissender
Des mit der eigenen Funnktion versuch ich mal.
Wobei mir nicht klar ist warum ein Flag in einer eigenen Funktion, in der eine Schleife läuft, anders ist als ein Flag in der Schleife selbst.
Oh, dann hab ich mich unklar ausgedrückt, ein Flag läuft hier genau wie in deiner Methode, es ist nur absolut unsauber die Behandlungsroutine mit einer Schleife zu verwenden!
Stell dir einfach mal vor, du bekommst 200 Byte gesendet. Da die Kommunikation asynchron ist, kommen die Bytes zufällig an. Nehmen wir mal den Fall an, es kommen erst 100 Byte, die lösen dein Event aus, es wird also einmal die Schleife gestartet und in Ruhe abgearbeitet. Währenddessen kommen nun auch irgendwann die nächsten 100 Byte an, jetzt wird wieder das Ereignis ausgelöst und hier läuft dann wieder das gleiche ab. Du reagierst also zweimal auf das Eintreffen von Daten in den Puffer.
Natürlich kannst du bei asynchroner Kommunikation nie sagen wann wieviele Daten im Puffer landen, also ist es garantiert nicht das von dir erwünschte Verhalten!
Wenn du jetzt aber eine eigene Methode verwendest, dann kannst du diese z.B. in einen Thread auslagern. Läuft dieser schon, dann liest der noch den aktuellen Puffer (und auch neu hinzukommende Zeichen) ein. Läuft der noch nicht, schmeißt du ihn an. Du kannst hier leicht abfangen, dass für jedes eintreffen von Daten ein eigener Thread gestartet wird.
Beendest du dann dein Programm, wird der Thread auch einfach nicht mehr neu gestartet (nur ein Beispiel einer möglichen Lösung). An den Flags ändert das natürlich nichts!
Zitat von
mymuschy:
Das mit der
Zitat:
Ereignisbehandlung im onClose abzuschalten (tC_SerialRxData := nil)
hab ich leider nicht verstanden. Wie geht denn das?
Nun ja, Delphi verwendet um das Eintreten eines Ereingis zu signalisieren einen Methodenzeiger. Hier kannst du die Adresse einer Methode eintragen, die der erwarteten entspricht (also die richtigen Argumente hat). Tritt das Ereignis auf, wird geschaut ob die Adresse der Methode ungleich nil ist und wenn dies der Fall ist, wird die Methode mit der gespeicherten Adresse aufgerufen.
Wenn du im Objektinspektor doppelt auf ein Ereignis klickst, so wird für dich eine fertige Methode angelegt und der Editor springt in den Körper rein.
Hinter den Kulissen wird dabei einfach die Adresse dieser Methode als Methodenzeiger für das Ereignis gespeichert. Deswegen steht im Objektinspektor dann der Name der Methode.
Wenn du nun im Programm im OnCloseQuery einfach schreibst:
tc_serial.OnRxChar := nil;
dann wird die Ereignisbehandlung abgeschaltet. Kommt jetzt ein neues Zeichen im Puffer an, gibt es keinen der benachrichtigt wird.
Sauberer und mehr OO wäre es, auf der Ereignisbehandlung einfach ein Observer-Pattern (bzw. eine Implementierung dieses Pattern) aufzusetzen. Aber das ist dann noch eine andere Sache.