【发布时间】:2022-01-28 21:44:43
【问题描述】:
我有一个链接到多个动作块的缓冲块:
bufferBlock.LinkTo(consumerActionBlock1, linkOptions);
bufferBlock.LinkTo(consumerActionBlock2, linkOptions);
bufferBlock.LinkTo(consumerActionBlockN, linkOptions);
效果是缓冲区块累积项目,一旦工人消费者可以接受更多项目,它就会获取它们(消费者一次设置为一个项目)。像这样,我有 N 个工作线程,而它们都在同一个队列上工作。到目前为止一切顺利。
现在我有一个管道,其中有两个缓冲区块,每个缓冲区都有特定优先级的工作项:
bufferBlockPrioHigh.LinkTo(consumerActionBlockHigh1, linkOptions);
bufferBlockPrioHigh.LinkTo(consumerActionBlockHigh2, linkOptions);
bufferBlockPrioHigh.LinkTo(consumerActionBlockHighN, linkOptions);
bufferBlockPrioLow.LinkTo(consumerActionBlockLow1, linkOptions);
bufferBlockPrioLow.LinkTo(consumerActionBlockLow2, linkOptions);
bufferBlockPrioLow.LinkTo(consumerActionBlockLowN, linkOptions);
也不错。现在我想实现这样的行为,如果低优先级队列中没有任何内容,那么高优先级队列可以使用它的工作人员。我添加了这段代码:
bufferBlockPrioHigh.LinkTo(consumerActionBlockLow1, linkOptions, c => bufferBlockPrioLow.Count == 0);
bufferBlockPrioHigh.LinkTo(consumerActionBlockLow2, linkOptions, c => bufferBlockPrioLow.Count == 0);
bufferBlockPrioHigh.LinkTo(consumerActionBlockLowN, linkOptions, c => bufferBlockPrioLow.Count == 0);
这个想法是高优先级缓冲区将首先尝试将项目发送到它自己的动作块。如果它们都忙,它会尝试将它们发送到低优先级缓冲区的动作块,因为此时低优先级缓冲区是空的。
这似乎有效。但是,如果所有的 LinkTo 都失败了,会发生什么? IE。没有自己的工作人员可用,并且所有有条件的 LinkTos 也会返回 false(即低优先级队列本身已满)? 整个任务现在是否会因为新的条件 LinkTos 而失败,或者一旦有条件或非条件的操作块空闲,任务最终会继续进行?
换句话说,我正在寻求了解何时评估多个 LinkTo 以及评估多少次。
【问题讨论】:
-
为什么会有一系列
consumerActionBlock1、consumerActionBlock2...consumerActionBlockN,而不是一个consumerActionBlock配置MaxDegreeOfParallelism = N? -
哪些块(如果有)配置了有限的
BoundedCapacity? -
所有消费者操作块的容量为 1。原因是为了控制确切的工人数量(以及背后的原因:资源。系统在重负载下变慢)。既然你这么说,可能只是设置 MaxDegreeOfParallelism 也一样
-
我发现了一个可能相关的问题:TPL DataFlow, link blocks with priority?
标签: c# .net task-parallel-library tpl-dataflow