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.
The best approach is to have some mechanism to actively detect the thing becoming true (rather than passively polling for it having become true); this could be any kind of wait-handle, or maybe a
TaskwithWait, or maybe aneventthat you can subscribe to to unstick yourself. Of course, if you do that kind of “wait until something happens”, that is still not as efficient as simply having the next bit of work done as a callback, meaning: you don’t need to use a thread to wait.TaskhasContinueWithfor this, or you can just do the work in aneventwhen it gets fired. Theeventis probably the simplest approach, depending on the context.Task, however, already provides most-everything you are talking about here, including both “wait with timeout” and “callback” mechanisms.And yes, spinning for 10 seconds is not great. If you want to use something like your current code, and if you have reason to expect a short delay, but need to allow for a longer one – maybe
SpinWaitfor (say) 20ms, and useSleepfor the rest?Re the comment; here’s how I’d hook an “is it full” mechanism:
with, in the “put back into the collection” code: