Uhrzeit anzeigen mit 2 Timer ohne verzögerung

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    Wozu brauchst Du genau 2 Timer? Laut Deiner Beschreibung reicht es doch, wenn ein Timer jede Sekunde tickt und Date.Now an ein Anzeige-CE überträgt, ggf. noch mit z.B. .ToShortTimeString formatiert.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Simo1991 Der Fehler der angezeigten zur PC-Zeit ist im Prinzip der halbe Timer-Takt.
    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!
    @VaporiZed 2 timer, 1 macht nur die überprüfung von der eingegebene value und 1 timer nur für die Anzeige, ich bin auch am überlegen ob reicht nur einen, aber kann das die Ursache sein für die verzögerung ?

    @RodFromGermany Danke, heisst das gibts kein möglichkeit dass sie genau gleich sind ?

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

    @Simo1991 Die Systemuhr sendet leider kein Event.
    Wenn Du das Intervall auf 100 Millisekunden stellst, hast Du einen Fehler von 50 Millisekunden, das ist 1/20 s, das sollte doch genügen.
    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!

    Simo1991 schrieb:

    anfangszeit und Endzeit [...] aber kann das die Ursache sein für die verzögerung ?
    Ich versteh einfach nicht, was Dein Programm(abschnitt) machen soll. Lassen wir mal den Timer1 raus. Wenn Timer2 und Uhrzeit (nahezu) synchron sein sollen, dann errechne beim Aktivieren von Timer2 die Zeitdifferenz bis zur nächsten vollen Sekunde und stell diese Differenz als Timer-Intervall ein. Und im Timer_Tick-EventHandler schreibst Du dann, dass das Intervall wieder 1000 (ms) ist und das das Anzeige-CE das Jetzt anzeigen soll.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Simo1991 schrieb:

    10 ms
    ist nicht sinnvoll.
    Was soll den an dem "Unterschied" nicht gemerkt werden?
    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!

    Simo1991 schrieb:

    ich meinte die Aktuelle Uhrzeit in meinem Rechner mit die angezeigte Uhrzeit im Label
    Genügt dir da folgendes etwa nicht ?

    VB.NET-Quellcode

    1. Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    2. SetTime()
    3. Timer1.Interval = 1000
    4. Timer1.Start()
    5. End Sub
    6. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    7. SetTime()
    8. End Sub
    9. Private Sub SetTime()
    10. Label1.Text = DateTime.Now.ToLongTimeString
    11. End Sub
    @VB1963 Da könnte die im Programm angezeigte Zeit gegenüber der PC-Zeit deutlich wahrnehmbar verschoben sein.
    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!

    RodFromGermany schrieb:

    Zeit gegenüber der PC-Zeit deutlich wahrnehmbar verschoben sein.
    Also ich habe beide Anzeigen gegenübergestellt - ich muss sagen, dass ich mit meinen müden Augen keinen Unterschied feststellen konnte...
    Das die Programmzeit zur PC-Zeit nachhinkt, ist klar - aber meines Erachtens nicht sichtbar für's menschliche Auge...
    Es hängt auch davon ab, bei welchen Bruchteil der aktuellen Sekunden der Tick kommt. Bei einen Interval von 1s, kann die Verzögerung schon sichtbar werden, je mehr Ticks pro Sekunde umso geringer die Wahrscheinlichkeit einen Unterschied bemerken zu können.

    Ist gerade die Sekunde vorbei, der TimerTick aber 1/10s davor war, sind ~900ms differenz da, was ja fast eine Sekunde ist.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin
    Was uns wieder zu Post#7 bringt ...
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja irgendwie schon. Aber beim Timer kann man sich nicht drauf verlassen, das jeder Tick wirklich alle exakt 1000ms kommt, da ist die Anpassung flott wieder hinfällig.

    Timer mit intervall 1000, beim Tick die aktuellen Millisekunden ausgeben, da sieht man die Abweichung
    124
    138
    151
    166
    180
    194
    207
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

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

    Dann Plan B: Ich verkrassisiere das Ganze:

    VB.NET-Quellcode

    1. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    2. Label1.Text = Date.Now.ToString
    3. Label2.Text = Date.Now.Millisecond.ToString
    4. Timer1.Interval = 1000 - Date.Now.Millisecond
    5. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich weiss jetzt nicht genau wie genau die anderen Timer sind (Timers.Timer, Threading.Timer), aber dieser selbsgebaute ist verdammt präzise. Einmal beim starten auf ein paar Millisekunden nach Sekundensprung stellen. Sollte auch gut sein. Wie man sieht, kann dieser Timer fast garnicht falsch gehen, habe die höchste abweichung die ich bisher hatte war echt nur 1ms. Code nochmal verbessert, jetzt kommt der Tick immer wenige MS nach den System-Sekundensprung, nach wenigen Ticks hat sich das eingespielt. Mehr präzision ist kaum noch möglich.

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Public Class Form1
    3. Private WithEvents Ticker As BetterTimer
    4. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    5. Ticker = New BetterTimer(Me)
    6. Ticker.Start()
    7. End Sub
    8. Private Sub Ticker_Tick() Handles Ticker.Tick
    9. Debug.WriteLine(Now.Millisecond)
    10. End Sub
    11. End Class
    12. Public Class BetterTimer
    13. Public Event Tick()
    14. Private Interval As Long = Stopwatch.Frequency
    15. Private NextTick As Long = 0
    16. Private Active As Boolean
    17. Private Runner As Thread
    18. Private Owner As Control
    19. Public Sub New(ByVal ctrl As Control)
    20. Owner = ctrl
    21. End Sub
    22. Public Sub Start()
    23. Active = True
    24. Runner = New Thread(AddressOf Running)
    25. Runner.Start()
    26. End Sub
    27. Public Sub Running()
    28. NextTick = Stopwatch.GetTimestamp + Interval
    29. While Active
    30. If Stopwatch.GetTimestamp >= NextTick Then
    31. Try
    32. If Now.Millisecond > 10 Then
    33. NextTick -= Now.Millisecond * 1500
    34. End If
    35. Owner.BeginInvoke(Sub() RaiseEvent Tick())
    36. Catch ex As Exception
    37. Active = False
    38. End Try
    39. NextTick += Interval
    40. End If
    41. End While
    42. End Sub
    43. Public Sub [Stop]()
    44. Active = False
    45. End Sub
    46. End Class

    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „NoIde“ ()

    Ja OK, für eine Uhr etwas viel, so ähnlich hatte ich damals GameLoops gemacht, da brauchte ich ja Präzision.

    Hier kann man den Thread auch locker noch 500ms - 750ms nach feuern des Events schlafen legen, so habe ich auf einen Kern nur wenige prozent last.

    So geändert habe ich beim 4-Kerner "nur" 6-7% CPU last insgesamt.

    VB.NET-Quellcode

    1. Public Sub Running()
    2. NextTick = Stopwatch.GetTimestamp + Interval
    3. While Active
    4. If Stopwatch.GetTimestamp >= NextTick Then
    5. Try
    6. If Now.Millisecond > 10 Then
    7. NextTick -= Now.Millisecond * 1000
    8. End If
    9. Owner.BeginInvoke(Sub() RaiseEvent Tick())
    10. Thread.Sleep(750)
    11. Catch ex As Exception
    12. Active = False
    13. End Try
    14. NextTick += Interval
    15. End If
    16. End While
    17. End Sub


    Nachdem ich noch ein wenig mit den Werte gespielt habe kam ich auf 3-4% Gesamt-Last.(nicht mit den Werten im Code). Brauchte dann aber ein wenig länger um sich "einzupendeln".
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „NoIde“ ()