Wird das Programm nach dem Aufruf von sleep in einer Methode weiterhin im Hintergrund ausgeführt (ohne neuen Thread zu erstellen)? Wenn ich in einem neuen Thread den Ruhezustand aufrufe, wird der Hauptthread dann seine Arbeit fortsetzen?
Jay Nirgudkar
@ JayNirgudkar Der Thread, der Sleep aufruft, wird gestoppt. Andere Threads sind nicht betroffen.
Isak Savo
Dies ist nicht garantiert korrekt.
Akumaburn
150
Grundsätzlich gibt es 3 Möglichkeiten, in (fast) jeder Programmiersprache zu warten:
Lose warten
Ausführen von Thread-Blöcken für eine bestimmte Zeit (= verbraucht keine Verarbeitungsleistung)
Für blockierte / wartende Threads ist keine Verarbeitung möglich
Nicht so genau
Enges Warten (auch enge Schleife genannt)
Der Prozessor ist während des gesamten Warteintervalls SEHR ausgelastet (tatsächlich verbraucht er normalerweise 100% der Verarbeitungszeit eines Kerns).
Einige Aktionen können während des Wartens ausgeführt werden
Sehr präzise
Kombination der vorherigen 2
Es kombiniert normalerweise eine Verarbeitungseffizienz von 1 und Genauigkeit + Fähigkeit, etwas von 2 zu tun.
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 possibleif(stopwatch.ElapsedMilliseconds>= millisecondsToWait){break;}}
Wir könnten auch DateTime.Nowoder andere Mittel zur Zeitmessung verwenden, sind aber Stopwatchviel 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 POSSIBLEif(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.
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.
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);}
Antworten:
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.quelle
Grundsätzlich gibt es 3 Möglichkeiten, in (fast) jeder Programmiersprache zu warten:
für 1. - Lose Wartezeit in C #:
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:
Wir könnten auch
DateTime.Now
oder andere Mittel zur Zeitmessung verwenden, sind aberStopwatch
viel schneller (und dies würde wirklich in einer engen Schleife sichtbar werden).für 3. - Kombination:
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).
quelle
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.quelle
Da Sie jetzt über die Async / Wait-Funktion verfügen, können Sie 50 ms lang am besten mit Task.Delay schlafen:
Wenn Sie auf .NET 4 (mit Async CTP 3 für VS2010 oder Microsoft.Bcl.Async) abzielen, müssen Sie Folgendes verwenden:
Auf diese Weise blockieren Sie den UI-Thread nicht.
quelle
FlushAsync
Version.async
Erklärung erforderlich ist, ist der AnrufTask.Delay(50).Wait();
Verwenden Sie diesen Code
quelle
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.
quelle
Zur besseren Lesbarkeit:
quelle
Ab .NET Framework 4.5 können Sie Folgendes verwenden:
quelle
Beste aus beiden Welten:
quelle