簡體   English   中英

“有界”BatchBlock => ActionBlock。如何完成正確的方法?

[英]“bounded” BatchBlock => ActionBlock. How to complete the proper way?

我正在嘗試使用鏈接到操作塊的有界批處理塊。 我知道批處理塊中的項目進料結束時我想觸發完成鏈。

問題是:如果我的BatchBlock<T>屬於給定的BoundedCapacity我將不會在動作塊中觸發所有項目。

這是我的問題的一個示例,它應該(在我對TPL數據流的理解......)中打印0到124,但最終打印0到99。

必須有一些我缺少的東西...也許BoundedCapacity意味着“當隊列數超過xxx時丟棄項目......”如果是這樣,我怎樣才能實現保證的最大內存消耗?

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks.Dataflow;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            int itemsCount = 125;
            List<int> ints = new List<int>(itemsCount);
            for (int i = 0; i < itemsCount; i++)
                ints.Add(i);

            BatchBlock<int> batchBlock = new BatchBlock<int>(50,new GroupingDataflowBlockOptions(){BoundedCapacity = 100});
            ActionBlock<int[]> actionBlock = new ActionBlock<int[]>(intsBatch =>
            {
                Thread.Sleep(1000);
                foreach (int i in intsBatch)
                    Console.WriteLine(i);               
            });
            batchBlock.LinkTo(actionBlock, new DataflowLinkOptions() { PropagateCompletion = true });

            // feed the batch block
            foreach (int i in ints)
                batchBlock.Post(i);
            // Don't know how to end the proper way... Meaning it should display 0 to 124 and not 0 to 99
            batchBlock.Complete();
            batchBlock.TriggerBatch();
            actionBlock.Completion.Wait();
        }
    }
}

Post塊上並不總是成功。 它嘗試將消息發布到塊,但如果達到BoundedCapacity ,它將失敗並返回false

你可以做的是使用SendAsync而不是返回一個等待的任務。 如果塊有空間用於您的消息,則它將異步完成。 如果沒有,那么該塊返回一個任務,當它有空間接受新消息時將完成。 您可以等待該任務並限制插入:

async Task MainAsync()
{
    var ints = Enumerable.Range(0, 125).ToList();
    var batchBlock = new BatchBlock<int>(50, new GroupingDataflowBlockOptions { BoundedCapacity = 100 });
    var actionBlock = new ActionBlock<int[]>(intsBatch =>
    {
        Thread.Sleep(1000);
        foreach (var i in intsBatch)
            Console.WriteLine(i);
    });
    batchBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true });

    foreach (var i in ints)
        await batchBlock.SendAsync(i); // wait synchronously for the block to accept.

    batchBlock.Complete();
    await actionBlock.Completion;
}

暫無
暫無

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

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