Is it efficient to
SpinWait.SpinUntil(() => myPredicate(), 10000)
for a timeout of 10000ms
or
Is it more efficient to use Thread.Sleep
polling for the same condition For example something along the lines of the following SleepWait
function:
public bool SleepWait(int timeOut) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (!myPredicate() && stopwatch.ElapsedMilliseconds < timeOut) { Thread.Sleep(50) } return myPredicate() }
I'm concerned that all the yielding of SpinWait may not be a good usage pattern if we are talking about timeouts over 1sec? Is this a valid assumption?
Which approach do you prefer and why? Is there another even better approach?
Update - Becoming more specific:
Is there a way to Make BlockingCollection Pulse a sleeping thread when it reaches bounded capacity? I rather avoid a busy waits alltogether as Marc Gravel suggests.
SpinWait is a lightweight synchronization type that you can use in low-level scenarios to avoid the expensive context switches and kernel transitions that are required for kernel events.
SpinWait essentially puts the processor into a very tight loop, with the loop count specified by the iterations parameter. The duration of the wait therefore depends on the speed of the processor.
In .NET 4 SpinWait
performs CPU-intensive spinning for 10 iterations before yielding. But it does not return to the caller immediately after each of those cycles; instead, it calls Thread.SpinWait
to spin via the CLR (essentially the OS) for a set time period. This time period is initially a few tens of nano-seconds but doubles with each iteration until the 10 iterations are complete. This enables clarity/predictability in the total time spent spinning (CPU-intensive) phase, which the system can tune according to conditions (number of cores etc.). If SpinWait
remains in the spin-yielding phase for too long it will periodically sleep to allow other threads to proceed (see J. Albahari's blog for more information). This process is guaranteed to keep a core busy...
So, SpinWait
limits the CPU-intensive spinning to a set number of iterations, after which it yields its time slice on every spin (by actually calling Thread.Yield
and Thread.Sleep
), lowering its resource consumption. It will also detect if the user is running a single core machine and yield on every cycle if that is the case.
With Thread.Sleep
the thread is blocked. But this process will not be as expensive as the above in terms of CPU.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With