У меня есть несколько потоков, генерирующих элементы и вставляющих их в общий ConcurrentQueue
:
private ConcurrentQueue<GeneratedItem> queuedItems = new ConcurrentQueue<GeneratedItem>();
private void BunchOfThreads () {
// ...
queuedItems.Enqueue(new GeneratedItem(...));
// ...
}
У меня есть еще один отдельный потребительский поток, но время от времени он должен работать в контексте этого приложения, иногда , ему просто нужно захватить все , находящееся в данный момент в очереди потоков, удалив его из этой очереди, все за один выстрел. Что-то вроде:
private Queue<GeneratedItem> GetAllNewItems () {
return queuedItems.TakeEverything(); // <-- not a real method
}
Я думаю, что я просмотрел всю документацию (для коллекции и ее реализованных интерфейсов), но я не нашел ничего похожего на «одновременно отбирать все объекты из очереди», или даже «одновременно поменять содержимое с другой очередью».
Я мог бы сделать это без проблем, если бы угробил ConcurrentQueue
и просто защитил нормальный Queue
с помощью lock
, например:
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;
}
}
Но мне нравится удобство ConcurrentQueue
, а также, поскольку я только учусь C#, мне интересно узнать об API; поэтому мой вопрос: есть ли способ сделать это с одной из одновременных коллекций?
Возможно, есть какой-нибудь способ получить доступ к любому объекту синхронизации, используемому ConcurrentQueue
, и заблокировать его для себя в своих целях, чтобы все хорошо играет вместе? Тогда я могу заблокировать его, взять все и отпустить?