问题 如何在TPL数据流中将多个目标块与源块链接?


我希望以下内容可以从两个发布者生成输出,但它只生成第一个输出:

var broadcastBlock = new BroadcastBlock<int>(null);
var transformBlock = new TransformBlock<int, int>(i => i*10);
var publish1 = new ActionBlock<int>(i => Console.WriteLine("Publisher 1:" + i));
var publish2 = new ActionBlock<int>(i => Console.WriteLine("Publisher 2:" + i));

broadcastBlock.LinkTo(transformBlock, new DataflowLinkOptions() { PropagateCompletion = true });
transformBlock.LinkTo(publish1, new DataflowLinkOptions() { PropagateCompletion = true });
transformBlock.LinkTo(publish2, new DataflowLinkOptions() { PropagateCompletion = true });

foreach (var i in Enumerable.Range(0, 5))
{
    broadcastBlock.Post(i);
}
broadcastBlock.Complete();
Task.WhenAll(publish1.Completion, publish2.Completion).Wait();

我显然在这里缺少一些基本的东西,任何想法?


9785
2018-04-25 10:51


起源



答案:


你正在联系2 ActionBlock单身 TransformBlock。你应该链接2 ActionBlock到了 BrodcastBlock 并链接 BroadcastBlock 到了 TransformBlock

你有什么:

BroadCast => Transfrom => ActionBlock
                       => ActionBlock

你需要什么:

Transfrom => BroadCast => ActionBlock
                       => ActionBlock

13
2018-04-25 11:12



谢谢回复。那么转换块无法直接链接到多个目标的问题,我们必须使用广播块作为中介吗?我可能错过了它,但没有看到文件暗示这一点。当我介绍其间的广播块时,它确实有效 - Amit G
@AmitG某些块可以链接到多个目标,但它们不会将项目“复制”到所有目标。对于每个项目,他们只发布到一个目标。 BroadcastBlock将项目提供给所有目标,直到其项目更改为止。 - i3arnon
这是我的理解 BroadcastBlock 只提供 最新 所有目标块的值。这意味着,如果 TransformBlock 在这个例子中有新的值, ActionBlocks 可能没有收到所有的价值 - 特别是如果他们需要更长的时间来消费 TransformBlock 产生。 - urbanhusky
@urbanhusky它只提供最新的接收,但它将传递给每个可以接受消息的链接目标块。 见文档。在最底层:“BroadcastBlock<T> 确保在允许元素被覆盖之前将当前元素广播到任何链接的目标。“ - Marc L.
@MarcL。它仍然不保证交付 所有 目标。如果您只需要其中一个目标来处理邮件,那也没关系 - 但如果您需要向所有目标投放,例如一个多路复用器块,那么你将不得不编写自己的块。 - urbanhusky


答案:


你正在联系2 ActionBlock单身 TransformBlock。你应该链接2 ActionBlock到了 BrodcastBlock 并链接 BroadcastBlock 到了 TransformBlock

你有什么:

BroadCast => Transfrom => ActionBlock
                       => ActionBlock

你需要什么:

Transfrom => BroadCast => ActionBlock
                       => ActionBlock

13
2018-04-25 11:12



谢谢回复。那么转换块无法直接链接到多个目标的问题,我们必须使用广播块作为中介吗?我可能错过了它,但没有看到文件暗示这一点。当我介绍其间的广播块时,它确实有效 - Amit G
@AmitG某些块可以链接到多个目标,但它们不会将项目“复制”到所有目标。对于每个项目,他们只发布到一个目标。 BroadcastBlock将项目提供给所有目标,直到其项目更改为止。 - i3arnon
这是我的理解 BroadcastBlock 只提供 最新 所有目标块的值。这意味着,如果 TransformBlock 在这个例子中有新的值, ActionBlocks 可能没有收到所有的价值 - 特别是如果他们需要更长的时间来消费 TransformBlock 产生。 - urbanhusky
@urbanhusky它只提供最新的接收,但它将传递给每个可以接受消息的链接目标块。 见文档。在最底层:“BroadcastBlock<T> 确保在允许元素被覆盖之前将当前元素广播到任何链接的目标。“ - Marc L.
@MarcL。它仍然不保证交付 所有 目标。如果您只需要其中一个目标来处理邮件,那也没关系 - 但如果您需要向所有目标投放,例如一个多路复用器块,那么你将不得不编写自己的块。 - urbanhusky