Do Loop in bestimmter Zeit......

  • VB.NET
  • .NET (FX) 4.0

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von kollimann.

    Do Loop in bestimmter Zeit......

    Servus, brauch mal bitte Hilfe.
    Aufgabe ist es 2 Variablen hochzählen in einer vorgegeben Zeit pro Gesamt-Durchlauf, und das mit weniger CPU Last wie ich es hinbekommen habe.
    Var1 0 bis 9
    Var2 1 - 127
    Var 1 wird erst erhöt wenn Var2 127 ist.............eigentlich ganz einfach.
    1 kompletter Durchlauf soll aber in einem vorgegebenen Zeitraum stattfinden,
    als Bsp. insgesamt 1270 Schritte in 250ms, wobei ich die Zeit bei Var1 einfach mal vernachlässige......macht pro Schritt/Durchlauf Var2 0,181ms
    bedeutet ich muss in der Schleife "bremsen"......das ist mein Problem. denn in meiner Variante mit meiner Do Loop hab ich ca 20-30% CPU Last.
    Eigentlich sollte ich den Thread bremsen, nur weiß ich das dass nur im 1ms Bereich geht. Daher die Frage, wie mach ich das Vorhaben ohne die CPU Last? Ich bräuchte 3 solcher Threads...macht locker 60% CPU für eigentlich nichts....

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Imports System
    3. Imports System.Diagnostics
    4. Public Class Form1
    5. Dim wert1 As Integer = 0
    6. Dim wert2 As Integer = 0
    7. Private thread_zaehlen As Thread
    8. Dim SW As New System.Diagnostics.Stopwatch
    9. Dim Button_1_Status As Boolean = False
    10. Dim millisekunden As Integer
    11. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    12. SW.Start()
    13. Label1.Text = ""
    14. Label2.Text = ""
    15. Label3.Text = ""
    16. End Sub
    17. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    18. If Button_1_Status = True Then
    19. thread_zaehlen.Abort()
    20. thread_zaehlen.Join()
    21. Button_1_Status = False
    22. Else
    23. Button_1_Status = True
    24. thread_zaehlen = New Thread(AddressOf zaehlen) 'neuen thread erstellen
    25. thread_zaehlen.IsBackground = True 'in background
    26. thread_zaehlen.Start() 'starten
    27. End If
    28. End Sub
    29. Public Sub zaehlen()
    30. Dim timestamp_start As Double
    31. Dim timestamp_durchlauf As Double
    32. Do
    33. For i = 0 To 9
    34. wert1 = i
    35. For i1 = 1 To 127
    36. timestamp_start = SW.ElapsedTicks * 1000000 / Stopwatch.Frequency ' Mikrosekunden Auflösung
    37. wert2 = i1
    38. ausgabe()
    39. Do Until SW.ElapsedTicks * 1000000 / Stopwatch.Frequency >= timestamp_start + 250
    40. Loop
    41. Next
    42. Next
    43. 'Ende 1 kompletten Durchlaufes......von vorn beginnen
    44. timestamp_durchlauf = SW.ElapsedTicks * 1000000 / Stopwatch.Frequency ' Mikrosekunden Auflösung ende eines durchlauf
    45. Me.Invoke(Sub() Me.Label3.Text = CStr((timestamp_durchlauf - timestamp_start)))
    46. Loop Until Button_1_Status = False
    47. End Sub
    48. Public Sub ausgabe()
    49. Me.Invoke(Sub() Me.Label1.Text = CStr(wert1))
    50. Me.Invoke(Sub() Me.Label2.Text = CStr(wert2))
    51. End Sub
    52. End Class


    Projekt im Anhang stammt aus VB Express 2012

    Bitte keine Fragen warum weshalb.........es ist so und muss irgendwie so gelöst werden
    Danke Heiko
    Dateien

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

    kollimann schrieb:

    Var1 0 bis 9
    Var2 1 - 127
    Soll das so etwas wie ein 127er System sein (analog zu dual, oktal, dezimal, hexadezimal)?
    Wenn ja, kannst Du einiges deutlich eleganter aufschreiben, Du brauchst dann nur eine entsprechende Variable.
    Und mach das ganze in einem Timer mit entsprechendem Intervall, da wird die GUI nicht ausgebremst.
    Dann invoke die Sub Ausgabe, nicht aber die Belegung von Label.Text.
    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!

    kollimann schrieb:

    nur weiß ich das dass nur im 1ms Bereich geht

    Richtig, mir ist kein Weg bekannt, mit dem du dein Vorhaben lösen könntest. Die minimalste Zeit, die du warten kannst ohne CPU-Last zu haben bekommst du, wenn du NtDelayExecution selbst mit -1 aufrufst. Das ist kürzer als Thread.Sleep(1), aber schwankt auf meinem System trotzdem zwischen 0,16ms und 2,3ms (durchschnitt ca. 0,9ms), also für dein Vorhaben noch zu viel. Vielleicht kennt noch jemand einen Trick oder andere Lösung, aber ich hatte mich auch mal ein Zeit lang damit beschäftigt und nichts kürzeres auf Windows gefunden.

    kollimann schrieb:

    Bitte keine Fragen warum weshalb.........es ist so und muss irgendwie so gelöst werden

    Wie heißt es so schön: Wer, wie was, warum, wer nicht fragt bleibt dumm.
    Wenn ich dich richtig verstehe möchtest du hier Hilfe, wenn ich helfe bin ich neugierig.

    Vor, gefühlt, Äonen von Jahren habe ich mal gelernt in Assembler die Zeit an Hand des CPU Taktes die Zeit zu berechnen und somit ein ​Sleep zu erreichen.
    Ich tippe mal das geht auch mit anderen Sprachen und vielleicht kann man das dann in VB.net aufrufen
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.

    MrTrebron schrieb:

    Vor, gefühlt, Äonen von Jahren habe ich mal gelernt in Assembler die Zeit an Hand des CPU Taktes die Zeit zu berechnen und somit ein Sleep zu erreichen.
    Ich tippe mal das geht auch mit anderen Sprachen und vielleicht kann man das dann in VB.net aufrufen

    Ja aber Moment mal, darum geht es doch gar nicht, oder? Das Sleep an sich funktioniert doch schon. Das Problem ist nur, dass dann der kern zu 100% ausgelastet wird, weil man halt nix macht außer warten bis die Zeit abgelaufen ist. Wenn man jetzt weniger CPU last habe will, muss man den Thread wieder zurück zum Windows Scheduler geben und sagen: komm so schnell es geht wieder zurück. Das kannst du mit NtDelayExecution oder einer der Funktionen die darunter liegen, aber selbst das ist für diese Vorhaben zu lange. Also ist die Frage praktisch: Gibt es einen kürzeres Sleep als NtDelayExecution(-1) vermutlich mittels Hardwareunterstützung oder so?
    ​Ja aber Moment mal, darum geht es doch gar nicht, oder? Das Sleep an sich funktioniert doch schon

    Richtig, ich nenne es mal, das Timing funktioniert, mit der "2. Do" wo sinnlos gewartet wird, so nenne ich das mal.
    Die Grundfrage bezieht sich eher darauf, wie löst man es eleganter bzw. mit weniger CPU Last für eigentlich nichts tun.

    kollimann schrieb:

    versteh ich nicht was du meinst. ... Aufgelöst wird das Ganze vom Empfänger mit (Var1*128+Var2)
    Beim Dezimalsystem hast Du Var1*10+Var2, beim Hexadezimalsystem Var1*16+Var2.
    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!
    ​Beim Dezimalsystem hast Du Var1*10+Var2, beim Hexadezimalsystem Var1*16+Var2.


    Sorry, ich kann dir dabei nicht folgen, das ist der Hass für mich.

    Bei mir heißt das Midi MSB und LSB, das kapier ich gerade so und es funktioniert ja wie gewollt, nur bisschen CPU Lastig, das liegt aber nicht an den Zahlen 8o