Further to Henk's answer, if you'd rather have the blocking ability of Take() but need to cancel out while its waiting on an empty list, you can handle cancellation out of the loop in this way.
private void DoSomething(CancellationToken token)
{
while (IsRunning)
{
MyObject next;
try
{
next = _queue.Take(token);
}
catch(OperationCanceledException)
{
break; //Cancelled
}
// Do something with 'next'
}
// Cleanup
}
Then, when 'whatever' happens that requires you to kill this loop, even if the list is empty and its stuck blocking on the Take() call, just call Cancel() on your CancellationTokenSource that generated the Token.
Note - For safety, its probably also advised to catch an ObjectDisposedException that Take() can also throw. Check the documentation for details around that and why it might throw.