【发布时间】:2017-02-03 04:58:51
【问题描述】:
我正在构建一个多线程 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 直到队列为空。但这具有生产线程也可能忙于生产的风险,这将导致收集没有有限的结束来减少和处理。我基本上是在寻找一种方法将所有内容从队列中取出,将其留空,但提供一个可以处理的集合。
【问题讨论】:
-
好的 api 设计不知道要添加什么,而是知道要包含什么不。 TryDrainTo() 和“此操作的行为未定义......”肯定使它很早就出现在切割清单上。线程安全是 .NET 风格的主要设计目标,当您添加自己的(扩展)方法时不要忽视这一点。
-
好吧,那么它可能会提供类似的方法,例如 TryTakeAll() 或类似的方法。现在看来我没有办法在特定时间点以原子方式取出队列中的所有元素。在我开始取出元素的那一刻,制作人可能会同时添加更多元素。
标签: c# multithreading queue