簡體   English   中英

如何使用 TPL 數據流庫指定無序執行塊?

[英]How can I specify an unordered Execution Block using the TPL Dataflow Library?

我想設置一個並行處理其項目的TransformBlock 因此,我將ExecutionDataflowBlockOptions.MaxDegreeOfParallelism設置為 > 1。我不關心消息的順序,但文檔說:

當您指定的最大並行度大於 1 時,將同時處理多條消息,因此,消息可能不會按接收順序進行處理。 但是,從塊中輸出消息的順序將是正確排序的。

“正確排序”是否意味着如果隊列中有一條消息需要較長的處理時間,則在處理完這條消息之前不會輸出更多消息?

如果是這樣,我如何指定一個不關心排序的執行塊(例如TransformBlock )? 還是我必須在消費端指定我不在乎訂購?

庫中沒有這樣的塊,但是您可以通過組合ActionBlockBufferBlock輕松地自己創建一個。 就像是:

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集合:實際上,這個塊的容量是選項中設置的容量的兩倍(因為兩個塊中的每一個都有一個單獨的容量)。

(將NPNelson評論升級為答案)

DataflowBlockOptions類包含一個可配置的屬性EnsureOrdered (於 2016 年引入),用於確定接收到的消息的順序是否將保留在塊的輸出中。 默認情況下,此屬性為true 將此屬性設置為false會使塊在處理消息后立即傳播消息,從而通過這種方式增加管道的吞吐量,因為傳播速度更快並減少了開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM