Timer unterbricht thread!?

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von picoflop.

    Timer unterbricht thread!?

    Hallo zusammen,

    ich habe folgendes Problem:

    Ich habe einen Thread erstellt, in dem eine Schleife läuft. Ich messe auch die Zykluszeit der Schleife. Diese Schleife darf durch nichts unterbrochen oder verzögert werden.
    Nun ist es aber so, ich habe noch einen Timer. Immer wenn der Timer überläuft und sein Sub anspringt, steigt für einen Zyklus lang die Zykluszeit. So als würde der Timerüberlauf kurzzeitig den Thread anhalten.
    Wie kann ich das verhindern? Ich habe schon versucht den Timer in einem eigenen Thread laufen zu lassen. Allerdings irgendwie ohne Erfolg.
    Oder gibt es noch eine andere Möglichkeit um die Schleife unterbrechungsfrei laufen zu lassen? In einer eigenen Classe etwa?

    Bin für jede Hilfe dankbar.

    Gruß
    Aber es muss doch eine Möglichkeit geben mehrere Funktionen gleichzeitig ablaufen zu lassen. Ich dachte es gibt sowas wie Multitasking?
    Wenn ich mehrere Anwendungen gleichzeitig öffne, laufen diese ja auch nebeneinander her, ohne sich gegenseitig zu beeinflussen oder?

    demmy schrieb:

    Aber es muss doch eine Möglichkeit geben mehrere Funktionen gleichzeitig ablaufen zu lassen.

    Definier bitte mal was du eigentlich willst ...

    Du willst eine Funktion die immer eine exakt definierte Zeitspanne dauert -> geht nicht.

    Du willst mehrere Sachen, die (quasi) zeitgleich laufen -> geht.

    Ich messe auch die Zykluszeit der Schleife. Diese Schleife darf durch nichts unterbrochen oder verzögert werden.

    Das GEHT NICHT! windows teilt einem Thread zwischen 10 und 15 ms zu (support.microsoft.com/kb/259025/en-us). Dann wird dieser Thread "geparkt" und ein anderer bekommt Rechenzeit. Andernfalls würde das ganze System nie zuverlässig funktionieren!
    Guten morgen.

    mhh nein, so exat muss es nicht sein, dass er immer die gleiche länge hat. Ich dachte nur, es gibt evtl. eine Möglichkeit das der Thread nicht von dem Timer der nebenher läuft unterbrochen bzw. beeinflusst wird. Das der Timer und der Thread parallel laufen? Das würde mir schon genügen. Denn immer wenn der Timer überläuft (1 x pro Sekunde) verdoppelt sich die Zykluszeit meiner Schleife. Stoppe ich den Timer bleibt die Zyklustzeit ziemlich konstant.

    Was ich noch vergessen habe, der Timer hat die Funktion Ein- und Ausgabefelder zu befüllen. Mit Werten die im Thread ermittelt werden, da dies ja nicht aus dem Thread heraus funktioniert. Vielleicht gibt es ja dafür eine elegantere Lösung. Um evtl. komplett auf den Timer zu verzichten?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „demmy“ ()

    Ich hatte ebenfalls Timer verwendet und bin nun auf GetTickCount umgestiegen. Der Grund dafür war ein Fehlverhalten für das in einem Forum der Timer verantwortlich gemacht wurde. Das war dann zwar nicht die Ursache, ich bin aber trotzdem bei GetTickCount geblieben weil es um mehrere Faktoren schneller ist als Timer - was sich natürlich erst ab einer bestimmten Menge von Aufrufen auswirkt. In jedem Fall ist der Effekt den die Zeitnahme auf die gemessene Zeit hat mit GetTickCount erheblich geringer. Bei Interesse stelle ich gerne die Messergebnisse für 1000 und 10.000 Messungen zur Verfügung.
    Ach ja und dann wäre noch zu erwähnen, dass GetTickCount die Millisekunden in einem Typ Long liefert und damit alle 49,7 Tage überläuft. Vielleicht bleibt Dein System ja nie so lange angeschaltet.

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

    Visual Basic-Quellcode

    1. Private Declare Function GetTickCount Lib "kernel32" () As Long ' Used for timing means
    2. Dim lStart As Long
    3. Dim a As String
    4. Dim i As Integer
    5. lStart = GetTickCount
    6. For i = 1 To 10000 ' bei 1000 wäre ist die Dauer evtl. noch 0 !
    7. a = a
    8. Next i
    9. MsgBox "Duration (msec)=" & GetTickCount - lStart

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „warbe“ () aus folgendem Grund: In Code Tags verpackt (damals war ich noch ein absoluter Neuling).

    warbe schrieb:

    Zumindest zeigen alle meine Messungen immer ein vergleichbares Ergebnis.

    Vergleichbar schlecht, meinst du?

    VB.NET-Quellcode

    1. For i = 1 To 10000 ' bei 1000 wäre ist die Dauer evtl. noch 0 !

    Tja, mit Stopwatch wär das nicht passiert ...

    VB.NET-Quellcode

    1. Dim stp = Stopwatch.StartNew
    2. For i = 1 To 1000
    3. ' mach gar nix
    4. Next
    5. stp.Stop()
    6. Debug.Print(stp.ElapsedTicks.ToString)

    Output: 16 - 17
    Daraus folgt: 17 Ticks => 17 * 100ns => 1.7 µs

    warbe schrieb:

    Fragt man sich dann am Ende wieso das nicht schon alle verwenden

    Weil es drölf Millionen Webseiten voll uralt Code gibt und jeder von da abschreibt? Und wenn man dann selbst was "veröffentlicht" ist es wieder uralt-Code?

    THEORETISCH ... müssten Betreiber von (Programmier-)Foren etc ab und zu mal ihren "Bestand" durchforsten und so 70-90% auf "obsolet" setzen ;)
    ich messe übrigens fast nie so kurze zeiten.
    Wennichwas schnelles messen will, lassichs einige 1000 mal durchlaufen, und messe dann.

    Ich hab sogar ein Benchmark-Timer gebastelt, der gibt eine bestimmte Zeit vor, und nudelt das zu messende in einer Dauerschleife durch. Ist die Zeit rum, wird ausgegeben, wieviele Umdrehungen geschafft wurden.

    Alles nicht sooo super-genau, aber zeitmessungen im Bereich von Millisekunden sind glaub wirklich mal so richtig ungenau.
    Windows ist nun mal ein Multitasking-Betriebssystem, während Deine Mess-Schleife läuft, kannst Du mit Word einen Brief schreiben.
    Wenn Du einen GUI-Timer nutzt, läuft der im GUI-Thread, der von Deinem Schleifen-Thread eigentlich sauber getrennt läuft.
    Nun kommt es darauf an, was für einen Prozessor Du hast, mit vielen Cores kannst Du da durchaus Glück haben, dass ein Thread einen Core quasi für sich hat.
    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!
    Das Thema hat mich noch etwas festgehalten. Meine aktuell einfachste und millisekundengenaue Lösung ist nun:

    Public Declare Function timeGetTime Lib "winmm.dll" () As Long

    Mit der einfachen Schleife:

    Public Sub Test()
    Dim i As Integer
    Dim l As Long
    For i = 1 To 100
    l = timeGetTime
    Debug.Print l
    Next i
    End Sub

    kann man die 1 msec Auflösung sehen.

    Mit dem "Pärchen":
    lStart = timeGetTime
    ...
    lTime = lStart - timeGetTime
    kann die abgelaufene Zeit gemessen werden.

    Jetzt fehlt jetzt nur noch eine Sleep-Funktion die ebenfall msec-genau ist, dann ist's für die die's ganz genau haben wollen/müssen perfekt.