如何设置高流量队列

时间:2015-04-13 14:30:47

标签: c# multithreading c#-4.0 blockingqueue

我正在尝试设置一个并发队列,该队列将从一个线程入队的数据对象入队,而另一个线程将数据对象出列并处理它们。我使用了BlockingCollection<T>并使用GetConsumingEnumerable()方法创建了一个在简单使用中运行良好的解决方案。我的问题在于:

  1. 数据快速进入,数据项大约每50ms
  2. 排队
  3. 处理每件商品的时间可能会超过50毫秒
  4. 我必须在处理时维护数据项的顺序,因为某些数据项表示必须按正确顺序触发的事件。
  5. 在我的开发机器上,这是一个非常强大的设置,似乎截止时间约为60ms处理时间,让事情正常工作。除此之外,我还有一个问题,就是让队列连续增长(没有足够快地出列)或者以错误的顺序处理数据项,这取决于我如何设置处理关于是否/多少/我在哪里并行化。有没有人有任何提示/技巧/解决方案,或者可以指出我会帮助我吗?

    编辑:正如下面所指出的,我的问题很可能不在于排队结构本身,而在于尝试更快地出列和处理项目。是否有技巧/提示/等。用于分配处理工作,以便我可以在保持传入数据项的顺序的同时保持快速出列。

    编辑(再次):感谢您的所有回复!很明显,我需要为此付出更多的努力。这是一个很好的输入,但我认为这将有助于我指出正确的方向!我将再次回复我提出的解决方案或更详细的问题和代码示例!再次感谢。

    更新:最后,我们选择了一个由ConcurrentQueue支持的BlockingCollection。队列完美地满足了我们的需求。最后,正如许多人所提到的,关键是使处理方尽可能快速有效。真的没有办法解决这个问题。我们使用并行化,我们发现它有助于(在某些情况下它实际上会损害性能),在某些区域缓存数据,并试图避免锁定方案。我们确实设法使某些工作表现得足够好,以便处理方能够跟上数据更新的步伐。再次感谢所有参与回应的人!

3 个答案:

答案 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个独立的队列,一个用于按顺序处理的项目,一个用单个线程处理,另一个用多个线程排队。

我们需要了解有关输入和预期处理的更多信息。