Wie kann ich mein C # -Programm für 50 Millisekunden in den Ruhezustand versetzen?
Dies mag eine einfache Frage sein, aber ich habe einen vorübergehenden Moment des Hirnversagens!
Wie kann ich mein C # -Programm für 50 Millisekunden in den Ruhezustand versetzen?
Dies mag eine einfache Frage sein, aber ich habe einen vorübergehenden Moment des Hirnversagens!
Antworten:
System.Threading.Thread.Sleep(50);
Denken Sie jedoch daran, dass dies im Haupt-GUI-Thread die Aktualisierung Ihrer GUI blockiert (es wird sich "träge" anfühlen).
Entfernen Sie einfach das ;
, damit es auch für VB.net funktioniert.
Grundsätzlich gibt es 3 Möglichkeiten, in (fast) jeder Programmiersprache zu warten:
für 1. - Lose Wartezeit in C #:
Thread.Sleep(numberOfMilliseconds);
Der Windows-Thread-Scheduler bewirkt jedoch eine Genauigkeit von Sleep()
etwa 15 ms (sodass der Ruhezustand problemlos 20 ms warten kann, selbst wenn nur 1 ms gewartet werden soll).
für 2. - Enges Warten in C # ist:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
Wir könnten auch DateTime.Now
oder andere Mittel zur Zeitmessung verwenden, sind aber Stopwatch
viel schneller (und dies würde wirklich in einer engen Schleife sichtbar werden).
für 3. - Kombination:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do STILL POSSIBLE
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
Thread.Sleep(1); //so processor can rest for a while
}
Dieser Code blockiert den Thread regelmäßig für 1 ms (oder etwas länger, abhängig von der Zeitplanung des Betriebssystem-Threads), sodass der Prozessor für diese Blockierungszeit nicht ausgelastet ist und der Code nicht 100% der Prozessorleistung verbraucht. Zwischen dem Blockieren kann weiterhin eine andere Verarbeitung durchgeführt werden (z. B. Aktualisierung der Benutzeroberfläche, Behandlung von Ereignissen oder Durchführung von Interaktions- / Kommunikationsaufgaben).
Sie können in Windows keine genaue Ruhezeit angeben . Dafür benötigen Sie ein Echtzeit-Betriebssystem. Das Beste, was Sie tun können, ist eine Mindestschlafzeit anzugeben . Dann ist es an dem Scheduler, Ihren Thread danach aufzuwecken. Und rufen Sie niemals.Sleep()
den GUI-Thread auf.
Da Sie jetzt über die Async / Wait-Funktion verfügen, können Sie 50 ms lang am besten mit Task.Delay schlafen:
async void foo()
{
// something
await Task.Delay(50);
}
Wenn Sie auf .NET 4 (mit Async CTP 3 für VS2010 oder Microsoft.Bcl.Async) abzielen, müssen Sie Folgendes verwenden:
async void foo()
{
// something
await TaskEx.Delay(50);
}
Auf diese Weise blockieren Sie den UI-Thread nicht.
FlushAsync
Version.
async
Erklärung erforderlich ist, ist der AnrufTask.Delay(50).Wait();
Verwenden Sie diesen Code
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
Der Thread wird für die angegebene Zeit nicht für die Ausführung durch das Betriebssystem geplant. Diese Methode ändert den Status des Threads, um WaitSleepJoin einzuschließen.
Diese Methode führt kein Standard-COM- und SendMessage-Pumpen durch. Wenn Sie in einem Thread mit STAThreadAttribute schlafen müssen, aber Standard-COM- und SendMessage-Pumping ausführen möchten, sollten Sie eine der Überladungen der Join-Methode verwenden, die ein Timeout-Intervall angibt.
Thread.Join
Zur besseren Lesbarkeit:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
Beste aus beiden Welten:
using System.Runtime.InteropServices;
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/
private void accurateSleep(int milliseconds)
{
//Increase timer resolution from 20 miliseconds to 1 milisecond
TimeBeginPeriod(1);
Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < milliseconds)
{
//So we don't burn cpu cycles
if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
{
Thread.Sleep(5);
}
else
{
Thread.Sleep(1);
}
}
stopwatch.Stop();
//Set it back to normal.
TimeEndPeriod(1);
}