Search code examples
c#task-parallel-libraryconcurrent-queue

Is it safe to put TryDequeue in a while loop?


I have not used concurrent queue before.

Is it OK to use TryDequeue as below, in a while loop? Could this not get stuck forever?

var cq = new ConcurrentQueue<string>();
cq.Enqueue("test");

string retValue;

while(!cq.TryDequeue(out retValue))
{
    // Maybe sleep?
}

//Do rest of code

Solution

  • Yes it is safe as per the documentation, but it is not a recommended design.

    It might get "Stuck forever" if the queue was empty at the first call TryDequeue, and if no other thread pushes data in the queue after that point (you could break the while after N attempts or after a timeout, though).

    ConcurrentQueue offers an IsEmpty member to check if there are items in the Queue. It is much more efficient to check it than to loop over a TryDequeue call (particularly if the queue is generally empty)

    What you might want to do is :

    while(cq.IsEmpty)
    {
        // Maybe sleep / wait / ...
    }
    
    if(cq.TryDequeue(out retValue))
    {
    ...
    }
    

    EDIT: If this last call returns false: another of your threads dequeued the item. If you don't have other threads, this is safe, if you do, you should use while(TryDequeue)