2008-09-18 13 views
236

Jak ustawić program C# w stan uśpienia na 50 milisekund?Jak ustawić program C# w tryb uśpienia na 50 ms?

To może wydawać się łatwe pytanie, ale mam chwilową chwilę awarii mózgu!

+1

Re znakowane do VB.NET jako odpowiedź działa również tam. –

+0

Brak DrFloyd5; nie działa na VB.NET, prawda? – Zanoni

+14

Gdybym był w zespole VB.Net, dodałbym; jako znak komentarza do następnej wersji języka ... –

Odpowiedz

283
System.Threading.Thread.Sleep(50); 

Pamiętaj jednak, że robi to w głównym wątku GUI będzie blokować swoje GUI z aktualizacją (będzie czuć się „słaby”)

Wystarczy wyjąć ; aby pracować dla VB. także sieć.

+0

Po wywołaniu uśpienia w metodzie, czy program będzie dalej wykonywany w tle (bez tworzenia nowego wątku)? Ponadto, jeśli wezwę sen w nowym wątku, czy główny wątek będzie kontynuował swoją pracę? –

+0

@JayNirgudkar wątek, który wywołuje stan wstrzymania, zostanie zatrzymany. Inne wątki pozostają bez zmian. –

+0

To nie gwarantuje, że jest dokładne. – Akumaburn

10
Thread.Sleep 
31

użyć tego kodu

using System.Threading; 
// ... 
Thread.Sleep(50); 
14
Thread.Sleep(50); 

Nić nie zostanie zaplanowane do wykonania przez system operacyjny czas określony. Ta metoda zmienia stan wątku tak, aby obejmował wartość 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 przedział limitu czasu.

Thread.Join 
54

Nie można określić dokładnyczas uśpienia w systemie Windows. Potrzebujesz do tego systemu czasu rzeczywistego. Najlepsze co możesz zrobić, to podać czas uśpienia w minimalnej długości: . Następnie do harmonogramu, aby obudzić wątek po tym. I nigdy zadzwoń pod numer .Sleep() w wątku GUI.

139

Istnieją 3 możliwości wyboru dla oczekujących w (prawie) każdego języka programowania:

  1. Loose czeka
    • Wykonanie bloków wątku dla danego czasu (= nie zużywa mocy obliczeniowej)
    • Przetwarzanie nie jest możliwe na zablokowanym/oczekującym wątku
    • Niezbyt precyzyjne
  2. Szczelne oczekiwania (zwany również mocno pętla)
    • procesor jest bardzo zajęte dla całego okresu karencji (w rzeczywistości zazwyczaj zużywa 100% czasu przetwarzania jednego rdzenia)
    • niektóre działania mogą być przeprowadzone w czasie oczekiwania
    • Bardzo precyzyjny
  3. Kombinacja z poprzednich 2
    • Zwykle łączy wydajność przetwarzania równą 1. i dokładność + zdolność zrobienia czegoś z 2.

do 1. - Loose oczekujących w C#:

Thread.Sleep(numberOfMilliseconds); 

Jednak wątek okna harmonogramu powoduje acccuracy z Sleep() na około 15ms (tak uśpienia można łatwo czekać 20 ms, nawet jeśli zaplanowano, aby czekać tylko przez 1 ms).

2. Informacje - Tight oczekujących w C# jest:

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 lub inne sposoby mierzenia czasu, ale Stopwatch jest znacznie szybszy (a to naprawdę stają się widoczne w szczelne pętli).

do 3. - Kombinacja:

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 
} 

Kod regularnie blokuje nić na 1 ms (lub nieco więcej, zależnie od gwintu OS szeregowania) tak, procesor nie jest zajęta przez ten czas blokowania i kodu nie zużywa 100% mocy procesora. Inne przetwarzanie może nadal być wykonywane pomiędzy blokowaniem (na przykład: aktualizacja interfejsu użytkownika, obsługa zdarzeń lub wykonywanie czynności związanych z interakcją/komunikacją).

+1

[Timer] (https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx) może również zainteresować użytkownika –

38

Od teraz masz asynchroniczny/Oczekujcie cecha, najlepszym sposobem, aby spać do 50ms jest za pomocą Task.Delay:

async void foo() 
{ 
    // something 
    await Task.Delay(50); 
} 

Albo jeśli są kierowane .NET 4 (z Async CTP 3 dla VS2010 lub Microsoft.Bcl.Async), należy użyć:

async void foo() 
{ 
    // something 
    await TaskEx.Delay(50); 
} 

W ten sposób nie można blokować wątku interfejsu użytkownika.

+0

czy możesz odpowiedzieć.flush podczas tego opóźnienie, jeśli jest w pętli? –

+0

Nie, nie możesz. Wierzę, że istnieje wersja "FlushAsync". –

+4

Alternatywą, która nie wymaga deklaracji "asynchronicznej", jest wywołanie 'Task.Delay (50) .Wait();' – stuartd

3

Dla czytelności:

using System.Threading; 
Thread.Sleep(TimeSpan.FromMilliseconds(50)); 
0

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); 
    } 
Powiązane problemy