我正在尝试设置一个并发队列,该队列将从一个线程入队的数据对象入队,而另一个线程将数据对象出列并处理它们。我使用了BlockingCollection<T>
并使用GetConsumingEnumerable()
方法创建了一个在简单使用中运行良好的解决方案。我的问题在于:
50ms
在我的开发机器上,这是一个非常强大的设置,似乎截止时间约为60ms
处理时间,让事情正常工作。除此之外,我还有一个问题,就是让队列连续增长(没有足够快地出列)或者以错误的顺序处理数据项,这取决于我如何设置处理关于是否/多少/我在哪里并行化。有没有人有任何提示/技巧/解决方案,或者可以指出我会帮助我吗?
编辑:正如下面所指出的,我的问题很可能不在于排队结构本身,而在于尝试更快地出列和处理项目。是否有技巧/提示/等。用于分配处理工作,以便我可以在保持传入数据项的顺序的同时保持快速出列。
编辑(再次):感谢您的所有回复!很明显,我需要为此付出更多的努力。这是一个很好的输入,但我认为这将有助于我指出正确的方向!我将再次回复我提出的解决方案或更详细的问题和代码示例!再次感谢。
更新:最后,我们选择了一个由ConcurrentQueue支持的BlockingCollection。队列完美地满足了我们的需求。最后,正如许多人所提到的,关键是使处理方尽可能快速有效。真的没有办法解决这个问题。我们使用并行化,我们发现它有助于(在某些情况下它实际上会损害性能),在某些区域缓存数据,并试图避免锁定方案。我们确实设法使某些工作表现得足够好,以便处理方能够跟上数据更新的步伐。再次感谢所有参与回应的人!
答案 0 :(得分:2)
如果您在.NET 4.0
上使用TPL
,则可以调查TPL Dataflow
库的简单用法,因为此库(它不是第三方,它是&#39;来自Microsoft being distributed via NuGet的sa库提供了保存系统中正在处理的数据顺序的逻辑。
根据我的理解,你得到的数据将按顺序排列,你必须在每个数据项目上进行一些工作后才能掌握这些数据。您可以使用此TransformBlock
类或BufferBlock
linked with ActionBlock
:只需将数据放在其输入上,设置您需要在每个项目上运行的操作,并将此块与您的类链接需要(你甚至可以让它IObservable
来创建一个响应的用户界面。
正如我所说,TPL Dataflow
阻止了FIFO
队列逻辑,并且保存了行动结果的顺序。您可以使用它们编写的代码是面向多线程的(请参阅有关maximum degree of parallelizm in TPL Dataflow
的更多信息)。
答案 1 :(得分:0)
我认为您可以使用阻止队列。我在BlockingCollection中每秒排队数千条消息,开销非常小。我认为你应该做以下事情:
一般关注处理时间。 BlockingCollection的默认集合类型是ConcurrentQueue,因此默认情况下它是一个FIFO(先进先出)队列,所以其他东西似乎是错误的。
答案 2 :(得分:0)
某些数据项表示必须在其中触发的事件 正确的顺序。
然后,您可以区分依赖项并按顺序处理它们,同时并行处理其他项。也许你可以构建2个独立的队列,一个用于按顺序处理的项目,一个用单个线程处理,另一个用多个线程排队。
我们需要了解有关输入和预期处理的更多信息。