繁体   English   中英

使用.NET 4.0任务并行库强制执行任务顺序

[英]Enforcing Task Order using the .NET 4.0 Task Parallel Libraries

我有一个程序,有大量传感器以相当高的速率生成数据,而消费者则需要使用它。 消费者的消费率非常不同。

由于我使用的是IObserver / IObservable,所以简单的解决方案就是为每个事件创建一个Task,并将onNext()调用和数据包装在lamda中。 这非常有效,我很惊讶原始电话的开销很小。

问题是这些消费者中的一些需要严格执行的事件顺序,并且不能错过任何事件。 “PerferFairness”还不够好。

我提出的最佳解决方案是包装事件/ OnNext()对,而不是将Insert包装到ParallelQueue中,每个使用者一个队列,并在队列的另一端有一个线程来创建OnNext()调用。

这种方法存在三个直接问题。 它比Task / OnNext()包装解决方案慢得多。 ParallelQueue没有Blocking Dequeue(或者有?)所以实现有点棘手。 第三是这似乎是一个常见的问题,我无法想象没有一些方法可以强制执行我错过的订单,也许就像多个任务工厂共享一个底层池,每个工厂都有一些设置使得它们严格执行订购。

任何人都知道实现我想要做的事情的正确方法吗?

编辑:任何涉及每个消费者或生产者的线程的解决方案都不起作用。 生产者/消费者形成长链,每个有数百个。

TPL DataFlow库可能非常适合您的应用程序。 它通过数据流范例扩展了TPL,允许您配置处理图并在高性能执行环境中运行。

TPL Dataflow作为.NET 4上的库提供,应作为.NET 4.5的一部分提供。

没有评论强制部分排序的最佳抽象,但是如果你在ConcurrentQueue<T>周围使用BlockingCollection<T>包装器,那么将为你提供一个阻塞的Take操作来使元素出列。 例如:

// the default is ConcurrentQueue, so you don't have to specify, but if you
// wanted different behavior you could use e.g. ConcurrentStack

var coll = new BlockingCollection<int>(new ConcurrentQueue<int>());

coll.Add(5); // blocks if the collection is at max capacity

int five = coll.Take(); // blocks if the collection is empty

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM