简体   繁体   中英

Thread.Sleep SpinWait.SpinUntil weird behavior

I have the code bellow.

namespace SandBox
{
    static class Program
    {
        static ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
        static void Main()
        {
            Timer timer = new Timer(worker, null, 0, 3000);
            while (true)
            {
                SpinWait.SpinUntil(IsEmpty); //???? freezes up here
                string snippet;
                while (!queue.TryDequeue(out snippet))
                    Thread.Sleep(1);
                Console.WriteLine(snippet);
                Thread.Sleep(5000); //??????
            }
        }
        static void worker(object x)
        {
            queue.Enqueue("***___***___***");
        }

        static bool IsEmpty()
        {
            return queue.IsEmpty;
        }
    }
}

If I don't include Thread.Sleep(5000); it works as expected. However, if I do, it outputs only one line and after that is just freezes up at the SpinUntil part and won't output any more lines. If I stop it and check if queue.IsEmpty true, the debugger says it is in fact false! (The worker does get called periodically, I checked with a breakpoint.) What's more, IsEmpty is getting called as well and is returning false.

What is happening?

SpinWait.SpinUntil spins until the specified condition is satisfied. In you case the condition is IsEmpty , so it will spin until the queue is empty (or, if you will, while the queue is not empty).

Since with the wait you gave the thread time to put something into the queue, the spinner will keep spinning because it is in the thread that is supposed to empty the queue, but it can't because it is waiting on the spinner.

If it's easier to understand, SpinUntil(IsEmpty) is the same as saying SpinWhile(IsNotEmpty) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM