Czy po wywołaniu metody sleep w metodzie program będzie nadal działał w tle (bez tworzenia nowego wątku)? Ponadto, jeśli wywołam tryb uśpienia w nowym wątku, czy wątek główny będzie kontynuował pracę?
Jay Nirgudkar
@JayNirgudkar wątek, który wywołuje tryb uśpienia, zostanie zatrzymany. Nie ma to wpływu na inne wątki.
Isak Savo
Nie gwarantuje się, że będzie to dokładne.
Akumaburn,
150
Zasadniczo istnieją 3 opcje czekania w (prawie) dowolnym języku programowania:
Luźne czekanie
Wykonywanie bloków wątków dla danego czasu (= nie zużywa mocy obliczeniowej)
Przetwarzanie wątku zablokowanego / oczekującego nie jest możliwe
Nie tak precyzyjnie
Ciasne oczekiwanie (zwane również ciasną pętlą)
procesor jest BARDZO zajęty przez cały okres oczekiwania (w rzeczywistości zwykle zajmuje 100% czasu przetwarzania jednego rdzenia)
Niektóre czynności można wykonać podczas oczekiwania
Bardzo dokładny
Połączenie poprzednich 2
Zwykle łączy wydajność przetwarzania 1. i precyzję + umiejętność zrobienia czegoś 2.
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 possibleif(stopwatch.ElapsedMilliseconds>= millisecondsToWait){break;}}
Możemy również użyć DateTime.Nowinnych środków pomiaru czasu, ale Stopwatchjest 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 POSSIBLEif(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.
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.
usingSystem.Runtime.InteropServices;[DllImport("winmm.dll",EntryPoint="timeBeginPeriod",SetLastError=true)]privatestaticexternuintTimeBeginPeriod(uint uMilliseconds);[DllImport("winmm.dll",EntryPoint="timeEndPeriod",SetLastError=true)]privatestaticexternuintTimeEndPeriod(uint uMilliseconds);/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/privatevoid accurateSleep(int milliseconds){//Increase timer resolution from 20 miliseconds to 1 milisecondTimeBeginPeriod(1);Stopwatch stopwatch =newStopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();while(stopwatch.ElapsedMilliseconds< milliseconds){//So we don't burn cpu cyclesif((milliseconds - stopwatch.ElapsedMilliseconds)>20){Thread.Sleep(5);}else{Thread.Sleep(1);}}
stopwatch.Stop();//Set it back to normal.TimeEndPeriod(1);}
Odpowiedzi:
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.źródło
Zasadniczo istnieją 3 opcje czekania w (prawie) dowolnym języku programowania:
dla 1. - Luźne oczekiwanie w C #:
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:
Możemy również użyć
DateTime.Now
innych środków pomiaru czasu, aleStopwatch
jest on znacznie szybszy (a to naprawdę stałoby się widoczne w ciasnej pętli).dla 3. - Połączenie:
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).
źródło
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.źródło
Ponieważ teraz masz funkcję asynchronizacji / oczekiwania, najlepszym sposobem na sen przez 50 ms jest użycie Task.Delay:
Lub jeśli celujesz w .NET 4 (z Async CTP 3 dla VS2010 lub Microsoft.Bcl.Async), musisz użyć:
W ten sposób nie zablokujesz wątku interfejsu użytkownika.
źródło
FlushAsync
wersja.async
deklaracji, jest zadzwonienieTask.Delay(50).Wait();
Użyj tego kodu
źródło
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.
źródło
Dla czytelności:
źródło
Począwszy od .NET Framework 4.5, możesz użyć:
źródło
Najlepsze z obu światów:
źródło