C# &引用;“有界”;BatchBlock=>;动作块。如何完成正确的方式?

C# &引用;“有界”;BatchBlock=>;动作块。如何完成正确的方式?,c#,.net,task-parallel-library,tpl-dataflow,C#,.net,Task Parallel Library,Tpl Dataflow,我尝试使用链接到动作块的有界batchblock。 我知道batchblock中项目的进给何时结束,我想触发一个完成链 问题是:如果我的BatchBlock具有给定的BoundedCapacity,我不会在操作块中激发所有项目 这是我的问题的一个示例,它应该(在我对TPL数据流的理解中…)打印0到124,但最终打印0到99 一定有什么我错过了。。。也许BoundedCapacity的意思是“当队列计数超过xxx时丢弃项目…”如果是这样,我如何实现保证的最大内存消耗 using System; u

我尝试使用链接到动作块的有界batchblock。 我知道batchblock中项目的进给何时结束,我想触发一个完成链

问题是:如果我的
BatchBlock
具有给定的
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();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Threading.Tasks.Dataflow;
命名空间控制台应用程序
{
班级计划
{
静态void Main(字符串[]参数)
{
int itemscont=125;
List ints=新列表(itemsCount);
对于(int i=0;i
{
睡眠(1000);
foreach(intsBatch中的inti)
控制台写入线(i);
});
LinkTo(actionBlock,新的DataflowLinkOptions(){PropagateCompletion=true});
//给批处理块喂料
foreach(整数中的整数i)
批处理柱(i);
//不知道如何以正确的方式结束…意味着它应该显示0到124,而不是0到99
batchBlock.Complete();
batchBlock.TriggerBatch();
actionBlock.Completion.Wait();
}
}
}

在块上发布
并不总是成功。它尝试向块发布消息,但如果达到
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;
}
async任务mainsync()
{
var ints=Enumerable.Range(0125.ToList();
var batchBlock=new batchBlock(50,new GroupingDataflowBlockOptions{BoundedCapacity=100});
var actionBlock=新actionBlock(intsBatch=>
{
睡眠(1000);
foreach(intsBatch中的var i)
控制台写入线(i);
});
LinkTo(actionBlock,新的DataflowLinkOptions{PropagateCompletion=true});
foreach(内部变量i)
等待batchBlock.SendAsync(i);//同步等待块接受。
batchBlock.Complete();
等待动作块完成;
}