Die Auflösung von Thread.Sleep () variiert zwischen 1 und 15,6 ms
Gegeben diese Konsolen App:
%Vor%Ich erwartete, dass die Ausgabe 100 Zahlen in der Nähe von 100 sein würde. Stattdessen bekomme ich etwas wie folgt:
99 99 99 100 99 99 99 106 106 99 99 99 100 100 99 99 99 99 101 99 99 99 99 99 101 99 99 99 99 101 99 99 99 100 99 99 99 99 99 103 99 99 99 99 100 99 99 99 99 813 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1560 1559 1559 1559 1559 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1559 1558 1558 1558 1558 1558
Aber manchmal bekomme ich keine genauen Ergebnisse; es wird jedes Mal ~ 1559 sein.
Warum ist es nicht konsistent?
Irgendein Googlen hat mir gezeigt, dass 15.6ms die Länge eines Zeitfensters sind, also erklärt das die ~ 1559 Ergebnisse. Aber warum bekomme ich manchmal das richtige Ergebnis und manchmal ein Vielfaches von 15,6? (z. B. Thread.Sleep (20) ergibt normalerweise ~ 31.2ms)
Wie wird es von Hardware oder Software beeinflusst?
Ich frage das wegen dem, was mich dazu gebracht hat, es zu entdecken:
Ich hatte meine Anwendung auf einem 32-Bit-Dual-Core-Rechner entwickelt. Heute wurde meine Maschine auf 64-Bit Quad-Core mit einer vollständigen OS-Neuinstallation aufgerüstet. (Windows 7 und .NET 4 in beiden Fällen, aber ich kann nicht sicher sein, dass die ältere Maschine W7 SP1 hatte; die neue tut.)
Beim Ausführen meiner Anwendung auf dem neuen Computer merke ich sofort, dass meine Formulare länger dauern, um auszublenden. Ich habe eine benutzerdefinierte Methode, um meine Formulare zu verblassen, die Thread.Sleep () mit Werten zwischen 10 und 50 verwendet. Auf dem alten System schien dies jedes Mal perfekt zu funktionieren. Auf dem neuen System dauert es viel länger zu verblassen, als es sollte.
Warum hat sich dieses Verhalten zwischen meinem alten System und meinem neuen System geändert? Handelt es sich um Hardware oder Software?
Kann ich es konsistent genau machen? (~ 1ms Auflösung)
Gibt es etwas, was ich in meinem Programm tun kann, um Thread.Sleep () zuverlässig auf ungefähr 1 ms genau zu machen? Oder sogar 10ms?
Ich kann eine meiner Fragen beantworten: Kann ich es immer korrekt machen? (~ 1ms Auflösung)
Ja, es scheint, als könnte ich timeBeginPeriod () und timeEndPeriod ().
Ich habe das getestet und es funktioniert.
Einige Dinge, die ich gelesen habe, legen nahe, dass das Aufrufen von timeBeginPeriod (1) für die Dauer der Anwendung keine gute Idee ist. Es sollte jedoch in Ordnung sein, es am Anfang einer kurzen Methode aufzurufen und dann mit timeEndPeriod () am Ende der Methode zu löschen.
Trotzdem werde ich auch die Verwendung von Timern untersuchen.
Die Antwort lautet nicht, Thread.Sleep
zu verwenden und stattdessen einen Timer mit hoher Auflösung zu verwenden. Sie müssen Ihre Einblendung in einer aktiven Schleife durchführen, aber das klingt, als wäre das kein Problem. Sie können einfach keine hohe Auflösung von Thread.Sleep
erwarten und es ist berüchtigt, dass sich das Verhalten auf anderer Hardware unterscheidet.
Sie können die Klasse Stopwatch
für .net verwenden, die verwendet wird Hochauflösende Leistungsindikatoren, wenn sie auf der Hardware unterstützt werden.
"Die Funktion Sleep setzt die Ausführung des aktuellen Threads für mindestens im angegebenen Intervall aus."
- & gt; Ссылка
Auf Ihrem Computer läuft ein Programm, das timeBeginPeriod () und timeEndPeriod () aufruft. In der Regel ein medienbezogenes Programm, das timeSetEvent () verwendet, um einen Timer mit einer Millisekunde festzulegen. Es beeinflusst auch die Auflösung von Sleep ().
Sie können diese Funktionen selbst festlegen, um konsistentes Verhalten zu erhalten. Für UI-Effekte jedoch nicht sehr vernünftig. Es ist ziemlich unfreundlich zu Akkulaufzeit auf einem Laptop.
Schlafen für 20 ms und tatsächlich 2/64 Sekunden ist logisch, die CPU wird einfach nicht früh genug aufwachen, um zu bemerken, dass 20 ms vergangen sind. Sie erhalten nur ein Vielfaches von 1/64 Sekunden. Eine vernünftige Wahl für einen Timer, der Fading-Effekte implementiert, ist 15 ms, was Ihnen eine Animation mit 64 fps im schlimmsten Fall bietet. Angenommen, dein Effekt zieht schnell genug an. Sie werden ein bisschen aus sein, wenn timeBeginPeriod aufgerufen wurde, aber nicht viel. Das Berechnen der Animationsstufe von der Uhr aus funktioniert auch, ist aber in meinem Buch etwas übertrieben.
Ihr Vorgehen ist falsch. Sie werden niemals schlafen, um genau zu sein, und je beschäftigt Ihr Gerät ist, desto mehr wird Ihr Schlaf-Loop falsch sein.
Was Sie tun sollten, ist zu sehen, wie viel Zeit vergangen ist und sich entsprechend anzupassen. Obwohl das Umdrehen von Sleep eine schlechte Idee ist, werden "bessere" Methoden wesentlich komplexer. Ich halte meine vorgeschlagene Lösung einfach.
Tags und Links .net thread-sleep