Ist es effizient zu
SpinWait.SpinUntil(() => myPredicate(), 10000)
für eine Zeitüberschreitung von 10000ms
oder
Ist es effizienter, Thread.Sleep
Polling für dieselbe Bedingung zu verwenden ? Zum Beispiel etwas in Anlehnung an die folgende SleepWait
Funktion:
public bool SleepWait(int timeOut)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (!myPredicate() && stopwatch.ElapsedMilliseconds < timeOut)
{
Thread.Sleep(50)
}
return myPredicate()
}
Ich mache mir Sorgen, dass die gesamte Ausbeute von SpinWait möglicherweise kein gutes Nutzungsmuster darstellt, wenn es sich um Zeitüberschreitungen über 1 Sekunde handelt. Ist das eine gültige Annahme?
Welchen Ansatz bevorzugen Sie und warum? Gibt es einen anderen noch besseren Ansatz?
Update - Spezifischer werden:
Gibt es eine Möglichkeit, BlockingCollection Pulse zu einem schlafenden Thread zu machen, wenn die begrenzte Kapazität erreicht ist? Ich vermeide es lieber, viel zu warten, wie Marc Gravel vorschlägt.
quelle
Monitor
dafür verwenden (wird ein Beispiel hinzufügen)Monitor.Wait
- aber nein: es wird nicht zum Stillstand kommen; Dies ist die normale und häufig verwendete Technik zur Verwendung eines Monitors als Signal.Wait
gibt die Sperre für die Dauer frei und erwirbt die Sperre erneut, bevor entweder true oder false zurückgegeben wird.In .NET 4
SpinWait
führt das CPU-intensive Drehen für 10 Iterationen durch, bevor es nachgibt. Es kehrt jedoch nicht unmittelbar nach jedem dieser Zyklen zum Anrufer zurück. Stattdessen wirdThread.SpinWait
aufgerufen, für einen festgelegten Zeitraum über die CLR (im Wesentlichen das Betriebssystem) zu drehen. Dieser Zeitraum beträgt anfangs einige zehn Nanosekunden, verdoppelt sich jedoch mit jeder Iteration, bis die 10 Iterationen abgeschlossen sind. Dies ermöglicht Klarheit / Vorhersagbarkeit in der gesamten Spinning-Phase (CPU-intensiv), die das System entsprechend den Bedingungen (Anzahl der Kerne usw.) abstimmen kann. WennSpinWait
es zu lange in der Phase der Spinausbeute bleibt, wird es regelmäßig in den Ruhezustand versetzt, damit andere Threads fortfahren können ( weitere Informationen finden Sie im Blog von J. Albahari ). Dieser Prozess hält garantiert einen Kern beschäftigt ...So
SpinWait
begrenzt die CPU-intensive Spinnen zu einer festgelegten Anzahl von Iterationen, wonach es auf jedem Spin seine Zeitscheibe ergibt (durch tatsächlich AufrufThread.Yield
undThread.Sleep
), dessen Ressourcenverbrauch zu senken. Es erkennt auch, ob der Benutzer eine Single-Core-Maschine ausführt, und gibt in jedem Zyklus nach, wenn dies der Fall ist.Mit
Thread.Sleep
dem Thread ist blockiert. Dieser Prozess ist jedoch in Bezug auf die CPU nicht so teuer wie der oben beschriebene.quelle