[英]How can I specify an unordered Execution Block using the TPL Dataflow Library?
我想設置一個並行處理其項目的TransformBlock
。 因此,我將ExecutionDataflowBlockOptions.MaxDegreeOfParallelism
設置為 > 1。我不關心消息的順序,但文檔說:
當您指定的最大並行度大於 1 時,將同時處理多條消息,因此,消息可能不會按接收順序進行處理。 但是,從塊中輸出消息的順序將是正確排序的。
“正確排序”是否意味着如果隊列中有一條消息需要較長的處理時間,則在處理完這條消息之前不會輸出更多消息?
如果是這樣,我如何指定一個不關心排序的執行塊(例如TransformBlock
)? 還是我必須在消費端指定我不在乎訂購?
庫中沒有這樣的塊,但是您可以通過組合ActionBlock
和BufferBlock
輕松地自己創建一個。 就像是:
public static IPropagatorBlock<TInput, TOutput>
CreateUnorderedTransformBlock<TInput, TOutput>(
Func<TInput, TOutput> func, ExecutionDataflowBlockOptions options)
{
var buffer = new BufferBlock<TOutput>(options);
var action = new ActionBlock<TInput>(
async input =>
{
var output = func(input);
await buffer.SendAsync(output);
}, options);
action.Completion.ContinueWith(
t =>
{
IDataflowBlock castedBuffer = buffer;
if (t.IsFaulted)
{
castedBuffer.Fault(t.Exception);
}
else if (t.IsCanceled)
{
// do nothing: both blocks share options,
// which means they also share CancellationToken
}
else
{
castedBuffer.Complete();
}
});
return DataflowBlock.Encapsulate(action, buffer);
}
這樣,一旦一個項目被ActionBlock
處理,它就會立即移動到BufferBlock
,這意味着不會保持排序。
這段代碼的一個問題是它沒有很好地觀察BoundedCapacity
集合:實際上,這個塊的容量是選項中設置的容量的兩倍(因為兩個塊中的每一個都有一個單獨的容量)。
DataflowBlockOptions
類包含一個可配置的屬性EnsureOrdered
(於 2016 年引入),用於確定接收到的消息的順序是否將保留在塊的輸出中。 默認情況下,此屬性為true
。 將此屬性設置為false
會使塊在處理消息后立即傳播消息,從而通過這種方式增加管道的吞吐量,因為傳播速度更快並減少了開銷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.