[英]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.