Timer oder BackgroundWorker und Sync

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Timer oder BackgroundWorker und Sync

    Hallo,

    ​ich schreibe eine Anwendung, die eine Reihe von Messgeräten auslesen und die Ergebnisse im Hauptformular grafisch und in TextBoxen anzeigen soll. Messintervall ist 1 Sekunde.

    ​Nun gibt es verschiedene Konzepte das umzusetzen.

    ​1) Timer im Hauptformular ruft Messroutine auf. Nachteil ist ein evtl. träges Verhalten des Hauptformulars. Hier sitzt der Op allerdings vorm Bildschirm und beobachtet die Werte und überträgt diese gelegentlich händisch in eine andere Anwendung. Große Aktivitäten gibt es nicht.

    ​2) BackgroundWorker in Dauerschleife mit Sleep am Ende der Schleife. Nachteil hier ist die problematische Synchronisation wenn der eigentliche Schleifendurchlauf unterschiedlich lange dauert

    ​3) BackgroundWorker und Timer. Timer setzt Startsignal für BGW, dieser startet und am Ende setzt der das Startflag zurück und legt sich Schlafen bis der Timer erneut ruft.

    ​4) wie 1) allerdings ruft der Timer nicht direkt die Messroutine auf sondern startet diese über den BGW, diesmal ohne Schleife sondern im Einzeldurchlauf. Das unterscheidet sich aber nicht wirklich von Variante 1) oder doch?


    ​Mir fehlt hier ein bisschen Hintergrundwissen über den Overhead der einzelnen Varianten, also wie lange es dauert, bis der BGW wirklich läuft, wie viel Speicher das braucht, ob es da signifikante Unterschiede gibt zwischen Variante 1 und 2 bzw. den anderen. Und macht das überhaupt was aus oder isses egal?

    Einschätzungen und Erfahrungswerte sind willkommen.

    Gruß

    MQ
    @MasterQ Willkommen im Forum. :thumbup:
    Ich würde einen System.Threading.Timer nehmen, der arbeitet eh asynchron, also in einem anderen Thread.
    Mach, was immer zu tun ist, und wenn die Resultate ausgewertet sind, invokst Du in den MainThread zur Anzeige.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Moin,

    Ich hatte mit dem WinForms-Timer angefangen und gerade mal als erstes und als letztes in der Eventroutine des Timers ein TickCount abgefragt. TickCount gibt wohl Millisekunden aus, so dass sich die Dauer meiner Messroutine im Bereich von 400ms bis 440ms bewegt. Es ist aber auch noch lange nicht alles an Messgeräten implementiert. Hier am Desktop laufen bisher 3, eins über LAN und zwei über RS232. Beim Roll-Out sind's dann zwei mehr, ebenfalls über RS232. Ganz am Ende kommen nochmal 3 hinzu, das kann dann 3 mal RS232 oder 3 mal USB, je nach Gerät sein. Es ist also zu erwarten, dass die Dauer noch deutlich nach oben gehen wird.

    Meine Messroutine ist bisher so aufgebaut.

    1) Abfrage aller Messgeräte, eins nach dem anderen. Der dadurch entstehende Zeitversatz von wenigen ms kann vernachlässigt werden.
    2) Auslesen von drei Datentabellen (DataTable) mit den bisherigen Messergebnissen um alle Messwerte der letzten Minute zu ermitteln
    3) Berechnen von Minutenmittelwerten
    4) neue Messwerte und Minutenmittelwerte in Datentabelle schreiben
    5) betroffenen Controls entweder direkt füllen (TextBoxen, 12 Stk) oder das DataBinding (Charts, 3 Stk.) aktualisieren
    fertig

    Hier gibt es sicherlich Raum für Optimierungen. Gerade Pkt 2, so fällt mir gerade auf, kann massiv optimiert werden, in dem ich die Tabelle nicht von vorne durchgehe sondern von hinten. Sind eh die letzten 60 Werte gefragt, dazu muss ich nicht jedesmal von vorne alle durchnudeln.

    Edit:
    ehm, sorry, ein Netzteil war nicht an und daher bin ich mit dem LAN-Gerät in den TimeOut. Länge der Messroutine jetzt zwischen 60 und 80ms.
    ​/Edit:


    MQ

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MasterQ“ ()

    Hey. Ich würde das gesamte Problem in 2 Programme aufteilen. Eine eigenständige Anwendung fragt die Messgeräte ab und sendet die Ergebnisse (Client/Server/NamedPipe etc.) an die zweite Anwendung. So entfällt bei der Hauptanwendung das Polling und Du hast 2 Probleme getrennt. Wäre mein Vorschlag.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Es ist dann "fast" egal, ob Du synchron (Windows.Froms.Timer) oder asynchron (BGW, System.Timers.Timer oder Async/Await) an das Problem herangehst. Ich würde die am Variante wählen, die am unanfälligsten für Fehler ist. Könntest evtl. auch das Abfragen der Messwerte auch als Console-Application oder Service implementieren.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @MasterQ Jein. ;)
    @SpaceyX spricht von zwei Programmen, Du von einem Thread.
    Statt des BGW würde ich einen richtigen Thjead nehmen, der in einer Endlosschleife Daten holt und bei Vorliegen von Ergebnissen an das Fenster ein entsprechendes Event sendet, damit dies sich die Daten abholen kann.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    MasterQ schrieb:

    TickCount gibt wohl Millisekunden aus
    Ein Tick sind üblicherweise 100 ns, also eine zehntausendstel Millisekunde.
    Zumindest wenn du DateTime.Ticks abfragst.

    Wenn du über Environment.TickCount gehst, ist es allerdings tatsächlich 1 ms (Millisekunden seit dem letzten Reboot).
    Microsoft ist da leider nicht so ganz konsistent.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    ErfinderDesRades schrieb:

    Entscheidend ist, wie lange die Messroutine braucht.
    Wenn die unter mw 200ms ist, dann ist Nebenläufigkeit fehl am Platze -> WinForms-Timer
    Von daher sehe ich hier erstma kein bedarf für BGW, Threads, Async, Asynchroner Timer, oder gar Zusatz-Programme.

    Muss ja auch eine Lösung sein, die der TE so einigermassen mit seinen Fähigkeiten gestemmt kriegt.

    petaod schrieb:

    Den My-Namespace
    Na ja ...

    VB.NET-Quellcode

    1. My.Settings
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!