Ankündigung

Einklappen
Keine Ankündigung bisher.

bei GroupValueReadReceived von Falcon gehen Telegramme verloren

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    bei GroupValueReadReceived von Falcon gehen Telegramme verloren

    Hallo zusammen,

    ich habe, auch mit HIlfe dieses Forums ("von VB.net mit Falcon über Weinzierl 332 zum KNX-Bus"), in VB.net (VS17) und Falcon 5.7.426 ein Programm realisiert, welches alle KNX-Telegramme am Bus mitliest - bei hoher KNX-Bus-Aktivität gehen aber Telegramme vorloren.

    ich öffne die Verbindung mit dem Bus:

    bus = New Bus(UsbConnectorParameters.FromAddress(f1KNXdev))
    AddHandler bus.GroupValueReceived, AddressOf BusOnGroupValueReceived
    bus.Connect()


    und empfange die Telegramme mit

    Private Sub BusOnGroupValueReceived(ReceivedValue As GroupValueEventArgs)

    ' ein KNX-Telegramm wurde empfangen - es steht in ReceivedValue in der Struktur GroupValueEventArgs
    ' -------------------------------------------------------------------------------------------------

    ' Gruppenadresse auf String GA umwandeln
    Dim GA As String
    GA = ReceivedValue.Address.ToString

    ' die Daten im Object Daten speichern - das ist ein Array von Bytes
    Dim daten
    daten = ReceivedValue.Value.Value

    ' Verarbeitung durch sleep simulieren
    System.Threading.Thread.Sleep(50) '50 msec warten

    End Sub


    wenn ich nun viele Telegramme gleichzeitig erzeuge (zB durch Aufruf einer Szene mit 30 Leuchten) dann gehen Telegramme verloren - je länger die Verarbeitung (simuliert durch den Sleep) dauert, umso mehr gehen verloren, bei 500msec bereits ganz deutlich!

    Ich hab schon "alles" probiert und finde ganz einfach keine bessere Programmierung (ist ja eh schon minimal) - zum Beispiel bei TCP werden bei hohem Nachrichten-Anfall mehrere gesendete Nachrichten in einer empfangenen Nachricht geblockt zugestellt und der Empfänger muss sie dann selbst auseinander-klabüsern - auch diese Analogie hat mir keine Erhellung gebracht...

    Zwei konkrete Fragen

    Kann mir jemand zuflüstern wie ich das besser/korrekt mache?
    Wir könnte ich erkenne, dass Nachrichten verloren gegangen sind?


    Ich hoffe da kann mir jemand helfen - Danke, freundliche Grüsse
    Franz

    PS: wie kann ich übrigends meinen Code in so "Kästchen" hervorheben?

    #2
    Hallo Franz,

    die Event-Verarbeitung sollte so schnell wie möglich passieren, 50 ms ist schon viel zu lang.
    Wenn du eine längere Zeit brauchst, solltest du die Daten in eine Queue stellen und asynchron verarbeiten.

    Gruß, Klaus

    Kommentar


      #3
      Danke, ja das verstehe ich - queue ist klar, aber wann ist der richtige Zeitpunkt die queue abzuarbeiten? und insbesondere das weitere Empfangen der Telegramme im Hintergrund zu ermöglichen? Da hab ich im Moment keine Idee?

      ich habe auch schon probiert sowas ähnliches zu machen (die Verarbeitung über events in eine andere Class mit Priorität "Background" zu verlagern) hat aber nichts gebracht, ist aber auch gut möglich, dass ich da (noch) etwas falsch mache, mit den events - vielleicht kann mir da jemand taugliche Realisierungs-Beispiele schicken?

      Was ich gerade probiere ist, das Verhalten der "FalconDemo" zu erforschen, dort scheint das Problem nicht aufzutreten (habe dort auch einen sleep eingebaut) - auch dazu ist natürlich jeder Hinweis willkommen.

      LG Franz

      Kommentar


        #4
        Hallo Franz,

        ich weiß ja nicht, was du mit dem Event vorhast, aber da gibt es viele Optionen. Asynchrone Eventhandler, verschiedene Producer-Consumer-Patterns. eine threadsichere Queue + ein Background-Thread zum Abarbeiten.

        Gruß, Klaus

        Kommentar


          #5
          Hallo Klaus,

          leider weiss ich nicht wirklich was da die Unterschiede sind - ich sehe das so: ich will einen Programmteil (tread?) der im Hintergrund läuft und die Einträge in einer Queue abarbeitet, was jeweils auch länger dauern kann - mit "im Hintergrund" meine ich, dass diese Verarbeitung jederzeit unterbrochen werden kann um ein eintreffendes KNX-Telgramm zu empfangen und in die Queue zur Bearbeitung einzureihen - ist das " threadsichere Queue + ein Background-Thread zum Abarbeiten" ?

          Möglicherweise sollte ich noch erwähnen, dass das Programm auf der "anderen Seite" mehrere TCP-Clients bedient - deren Anfragen kann ich aber ebenfalls über die queue mit den KNX-Telegrammen serialisieren...

          LG Franz

          Kommentar


            #6
            Was zum Lesen: https://docs.microsoft.com/de-de/dot...s/thread-safe/

            Kommentar


              #7
              Klaus, Danke, das erklärt sehr gut wie ich die Zugriffe auf die Queue threadsicher durchführe, Danke.

              Was ich noch nicht kapiert habe ist wie ich einen thread "in den HIntergrund schicke" (zur Langsamen Haupt-Verarbeitung), der sich jederzeit von von einem schnellen Thread unterbrechen lässt, um die KNX-Telegramme einzuqueuen, aber nicht umgekehrt - hast Du dafür auch so einen tollen Link?

              Kommentar


                #8
                ich habe jetzt auch meine Vergleichs-Untersuchungen in FalconDemo abgeschlossen (wohl wissend, dass in der IT nie etwas abgeschlossen ist) - und ich bin ratlos, dort tritt das Problem nicht auf, auch nicht bei einem sleep(500) - warum???

                private void BusOnGroupValueReceived(GroupValueEventArgs groupValueEventArgs)
                {
                if (_mainWindow.Dispatcher.CheckAccess())
                {
                if (groupValueEventArgs != null)
                {
                ResultText = ResultText +
                string.Format(
                "Address {0}, IndividualAddress {1}, TelegramPriority {2}, Value {3}",
                groupValueEventArgs.Address,
                groupValueEventArgs.IndividualAddress,
                groupValueEventArgs.TelegramPriority,
                groupValueEventArgs.Value) + Environment.NewLine;

                string zudru = DateTime.Now.ToString("HHmmss.fff") + string.Format( " Address {0}", groupValueEventArgs.Address);
                System.Diagnostics.Debug.Print(zudru);

                System.Threading.Thread.Sleep(500);
                System.Diagnostics.Debug.Print(DateTime.Now.ToStri ng("HHmmss.fff") + "nach sleep");
                }

                }
                else
                {
                _mainWindow.Dispatcher.BeginInvoke(new Action<GroupValueEventArgs>(BusOnGroupValueReceive d), groupValueEventArgs);
                }
                }


                Ich habe die unterstrichenen Zeilen eingefügt und an den Debug.Print's sehe ich, dass dazwischen wirklich 500ms gewartet wird - und trotzdem geht kein Telegramm verloren...

                Wie gesagt, ich bin ratlos - hat jemand dazu eine Idee? Danke.

                LG Franz

                Kommentar


                  #9
                  Das ist wegen dem
                  Code:
                  _mainWindow.Dispatcher.BeginInvoke(...)
                  - das startet die Aktion auf dem UI.Thread, wartet aber nicht darauf.

                  Bei "Übersicht über BlockingCollections" in der verlinkten Dokumentation ist ein Beispiel mit
                  Code:
                  Task.Run
                  . Du kannst aber auch mit
                  Code:
                  New Thread(...)
                  einen neuen Thread dafür starten.

                  Kommentar


                    #10
                    Danke Klaus, noch nicht verstanden, da muss ich mal tiefer rein, melde michwieder...

                    Kommentar


                      #11
                      Vielen Dank nochmals Klaus, Deine Tips haben mich auf die richtige Spur(en) gebracht!

                      Meine Realisierung
                      *) eine kleine schnelle "BusOnGroupValueReceived" Sub welche nur das empfangene Telegramm in eine Queue schreibt
                      *) in einem anderen Thread läuft die Verarbeitung - es werden die Telegramme aus der Queue heraus verarbeitet - die echte Verarbeitung simuliere ich dzt mit einem Random-Sleep (10-1000 msec)
                      *) die Verarbeitung hinkt dadurch natürlich bei vielen gleichzeitigen Telegammen hintnach (bis zu Sekunden), aber - alle Telegramme werden in der richtigen Reihenfolge verarbeitet
                      *) threadsicher mach ich das ganze durch synclock - diese sperre gilt jeweils nur ganz kurz während EnQueue und DeQueue - da ein Telegramm ja jeweils nur in einem Queue-Element verarbeitet wird sollte das auch meiner Meinung nach ausreichen
                      *) gegen den Proucer-Consumer Workflow (...Tasks.Dataflow package) habe ich mich entschieden weil 1) ich als alter Assembler-System-Programmierer immer gerne möglichst "maschinennahe" arbeite und damit nicht die Probleme einer fremden Abstraktionsebene auch noch zusätzlich habe, und 2) die Aufgabenstellung ja auch nicht so dramatisch umfangreich ist
                      *) Massentest hat mein Verarbeitungsrahmen jedenfalls bisher alle gemeistert!
                      *) heute Nacht läuft noch ein massiver Massentest...

                      Vielen Dank nochmals!

                      Wie kann ich eigentlich so eine Diskussion als "gelöst" kennzeichnen?
                      Und wie kann ich um Code-Snipplets so schöne Rahmen machen wie Du?

                      Liebe Grüsse
                      Franz

                      Kommentar


                        #12
                        Hallo Franz,

                        das freut mich, dass du einen Weg gefunden hast!

                        Code: den code markieren und den "#" Button in der Toolbar klicken.

                        Gruß, Klaus

                        Kommentar


                          #13
                          Moin,
                          ich klink mich mal mit ein.
                          Bin gerade auch dabei eine Visu mit einer UWP App zu realisieren.
                          Bisher habe ich auch die connection hinbekommen und lese via
                          Code:
                          _bus.GroupValueReceived
                          mit.
                          Auch schreiben funktioniert bereits sehr gut.

                          Tritt das Problem bei vielen Telegrammen allgemein so auf? Oder ist mir das einfach nur noch nicht aufgefallen?

                          Kommentar


                            #14
                            Guten Morgen Vico,

                            das klingt ja ganz gut!

                            Das Problem mit den vielen Telegrammen hängt natürlich von zwei Faktoren ab:
                            *) wie rasch kommen die Telegramme hintereinander? Grösse der KNX-Installation?
                            *) wie lange dauert die Verarbeitung eines Telegramms?

                            Ich betreibe eine grosse Installation, wo es auch mal richtig "prasselt" - und meine Verarbeitung dauert manchmal auch etwas länger, jedenfalls länger als ein paar Millisekunden - es kann Dir also auch noch gar nicht aufgefallen sein...

                            Viele Telegramme gleichzeitig erzeuge ich durch auslösen von Szenen mit vielen Leuchten und die Verarbeitungszeit simuliere ich durch einen Sleep - so kannst Du einmal einen Massentest wagen... und dann war bei mir schnell Overflow

                            Meinen Lösungsweg habe ich oben beschrieben.

                            Gutes Gelingen
                            Franz

                            Kommentar

                            Lädt...
                            X