簡體   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