如何批量使用BlockingCollection
我想出了一些代码来消耗队列中所有的wating项目。 而不是逐项处理项目,将所有等待项目作为一组处理是有意义的。
我已经宣布我的队列是这样的。
private BlockingCollection items = new BlockingCollection(new ConcurrentQueue);
然后,在消费者线程上,我打算像这样批量阅读这些项目,
Item nextItem; while (this.items.TryTake(out nextItem, -1)) { var workToDo = new List(); workToDo.Add(nextItem); while(this.items.TryTake(out nextItem)) { workToDo.Add(nextItem); } // process workToDo, then go back to the queue. }
这种方法缺乏GetConsumingEnumerable
,我不禁想知道我是否错过了更好的方法,或者我的方法是否存在缺陷。
有没有更好的方法来批量使用BlockingCollection
?
虽然在某些方面不如ConcurrentQueue
,但是我自己的LLQueue
允许使用AtomicDequeueAll方法进行批量出列,其中队列中的所有项目都是在单个(primefaces和线程安全)操作中从中获取的,然后在一个非线程安全的集合中供单个线程使用。 此方法专为要批量读取操作的方案而设计。
虽然它可以用来轻松地创建阻塞集合,但这并没有阻塞:
public BlockingBatchedQueue { private readonly AutoResetEvent _are = new AutoResetEvent(false); private readonly LLQueue _store; public void Add(T item) { _store.Enqueue(item); _are.Set(); } public IEnumerable Take() { _are.WaitOne(); return _store.AtomicDequeueAll(); } public bool TryTake(out IEnumerable items, int millisecTimeout) { if(_are.WaitOne(millisecTimeout)) { items = _store.AtomicDequeueAll(); return true; } items = null; return false; } }
这是一个不做以下事情的起点:
- 处理待处理的等待读者。
- 担心多个读者的潜在竞争都是由一个人正在阅读时发生的写入事件触发的(它只是考虑偶尔空的结果可以说是好的)。
- 在写作上放置任何上限。
所有这些都可以添加,但我希望保持最低限度的实际用途,希望在上面定义的限制范围内没有错误。