I have multiple threads generating items and sticking them in a common ConcurrentQueue
:
private ConcurrentQueue<GeneratedItem> queuedItems = new ConcurrentQueue<GeneratedItem>();
private void BunchOfThreads () {
// ...
queuedItems.Enqueue(new GeneratedItem(...));
// ...
}
I have another single consumer thread but the way it needs to work in the context of this application is, occasionally, it just needs to grab everything currently in the threads' queue, removing it from that queue, all in one shot. Something like:
private Queue<GeneratedItem> GetAllNewItems () {
return queuedItems.TakeEverything(); // <-- not a real method
}
I think I looked through all the documentation (for the collection and its implemented interfaces) but I didn't seem to find anything like a "concurrently take all objects from queue", or even "concurrently swap contents with another queue".
I could do this no problem if I ditch the ConcurrentQueue
and just protect a normal Queue
with a lock
, like this:
private Queue<GeneratedItem> queuedItems = new Queue<GeneratedItem>();
private void BunchOfThreads () {
// ...
lock (queuedItems) {
queuedItems.Enqueue(new GeneratedItem(...));
}
// ...
}
private Queue<GeneratedItem> GetAllNewItems () {
lock (queuedItems) {
Queue<GeneratedItem> newItems = new Queue<Event>(queuedItems);
queuedItems.Clear();
return newItems;
}
}
But, I like the convenience of the ConcurrentQueue
and also since I'm just learning C# I'm curious about the API; so my question is, is there a way to do this with one of the concurrent collections?
Is there perhaps some way to access whatever synchronization object ConcurrentQueue
uses and lock it for myself for my own purposes so that everything plays nicely together? Then I can lock it, take everything, and release?