我正在构建一个多线程C#应用程序,其中多个线程对队列中的元素有贡献。单个线程正在消耗同一队列上的元素。我希望单个线程对传入元素的元素进行一些缩减/合并,理想情况下,它会查看队列中的所有新元素,减少它们,然后在缩小后处理条目。有点像这样:
while (true)
{
Collection<Elem> elements = queue.TakeAll();
Collection<Elem> reducedElements = Reduce(elements);
for (Elem e in reducedElements)
{
process(e);
}
}
但显然没有任何TakeAll()方法。从Java经验来看,我已经习惯了BlockingQueue's drainTo method,它提供了我感兴趣的东西。
我可以通过使用TryTake自己实现一些东西,直到队列为空。但这样做的风险在于,生产线程可能也会忙于生成,这将导致集合没有有限的结束来减少和处理。我基本上都在寻找一种方法,将所有内容从队列中取出,将其留空但提供可以处理的集合。
答案 0 :(得分:0)
查看名称空间System.Collections.Concurrent中的ConcurrentQueue
。
此队列用于线程安全操作。
您可以轻松添加扩展方法用于您的目的。
public static class Extensions
{
public static List<T> DrainTo<T>(this System.Collections.Concurrent.ConcurrentQueue<T> poConcurrentQueue)
{
List<T> loList = new List<T>();
T loElement;
while (poConcurrentQueue.TryDequeue(out loElement))
loList.Add(loElement);
return loList;
}
}
并使用如下:
System.Collections.Concurrent.ConcurrentQueue<string> loConcurrentQueue = new System.Collections.Concurrent.ConcurrentQueue<string>();
loConcurrentQueue.Enqueue("Element1");
loConcurrentQueue.Enqueue("Element2");
var loList = loConcurrentQueue.DrainTo();