Jak sprawić, aby mój program C # spał przez 50 milisekund?
To może wydawać się łatwe pytanie, ale mam chwilową chwilę niewydolności mózgu!
Jak sprawić, aby mój program C # spał przez 50 milisekund?
To może wydawać się łatwe pytanie, ale mam chwilową chwilę niewydolności mózgu!
Odpowiedzi:
System.Threading.Thread.Sleep(50);
Pamiętaj jednak, że wykonanie tego w głównym wątku GUI zablokuje aktualizację GUI (będzie się wydawać „powolne”)
Wystarczy usunąć, ;
aby działało to również dla VB.net.
Zasadniczo istnieją 3 opcje czekania w (prawie) dowolnym języku programowania:
dla 1. - Luźne oczekiwanie w C #:
Thread.Sleep(numberOfMilliseconds);
Jednak harmonogram wątków w systemie Windows powoduje, że dokładność Sleep()
wynosi około 15 ms (więc tryb uśpienia może z łatwością czekać 20 ms, nawet jeśli zaplanowano, że czeka tylko 1 ms).
dla 2. - Ciasne oczekiwanie w C # to:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
Możemy również użyć DateTime.Now
innych środków pomiaru czasu, ale Stopwatch
jest on znacznie szybszy (a to naprawdę stałoby się widoczne w ciasnej pętli).
dla 3. - Połączenie:
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
}
Ten kod regularnie blokuje wątek przez 1ms (lub nieco dłużej, w zależności od planowania wątków systemu operacyjnego), więc procesor nie jest zajęty przez ten czas blokowania i kod nie zużywa 100% mocy procesora. Inne przetwarzanie może być nadal wykonywane pomiędzy blokowaniem (takie jak: aktualizacja interfejsu użytkownika, obsługa zdarzeń lub wykonywanie interakcji / komunikacji).
Nie można określić dokładnego czasu uśpienia w systemie Windows. Potrzebujesz do tego systemu operacyjnego w czasie rzeczywistym. Najlepsze, co możesz zrobić, to określić minimalny czas snu. Następnie program planujący musi obudzić Twój wątek. I nigdy nie wzywaj .Sleep()
wątku GUI.
Ponieważ teraz masz funkcję asynchronizacji / oczekiwania, najlepszym sposobem na sen przez 50 ms jest użycie Task.Delay:
async void foo()
{
// something
await Task.Delay(50);
}
Lub jeśli celujesz w .NET 4 (z Async CTP 3 dla VS2010 lub Microsoft.Bcl.Async), musisz użyć:
async void foo()
{
// something
await TaskEx.Delay(50);
}
W ten sposób nie zablokujesz wątku interfejsu użytkownika.
FlushAsync
wersja.
async
deklaracji, jest zadzwonienieTask.Delay(50).Wait();
Użyj tego kodu
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
Wątek nie będzie planowany do wykonania przez system operacyjny przez określony czas. Ta metoda zmienia stan wątku na WaitSleepJoin.
Ta metoda nie wykonuje standardowego pompowania COM i SendMessage. Jeśli chcesz spać w wątku, który ma STAThreadAttribute, ale chcesz wykonać standardowe pompowanie COM i SendMessage, rozważ użycie jednego z przeciążeń metody Join, która określa limit czasu.
Thread.Join
Dla czytelności:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
Najlepsze z obu światów:
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);
}