joinBlock的两个源只执行一次

时间:2018-03-28 17:10:06

标签: c# .net task-parallel-library tpl-dataflow

我应该使用哪个Block,以便每次first_source发布其值时都会调用操作块

我尝试过如下,只打印

8

但我想在屏幕上关注输出。

8  
6
4

动作块仅被调用一次,但我希望每次first_source发布其值时执行它。

TransformBlock<int, int> first_source = new TransformBlock<int, int>((val) => { return val * 2; });
TransformBlock<int, int> second_source = new TransformBlock<int, int>((val) => { return val/3; });
JoinBlock<int, int> joinBlock = new JoinBlock<int, int>();

ActionBlock<Tuple<int, int>> actionBlock = new ActionBlock<Tuple<int, int>>((valTuple) => {
    Console.WriteLine(valTuple.Item1 + valTuple.Item2);
});

var options = new DataflowLinkOptions()
{
    PropagateCompletion = true
};

first_source.LinkTo(joinBlock.Target1, options);
second_source.LinkTo(joinBlock.Target2, options);
joinBlock.LinkTo(actionBlock, options);

first_source.Post(3);
first_source.Post(2);
first_source.Post(1);
second_source.Post(6);
second_source.Complete();
first_source.Complete();

1 个答案:

答案 0 :(得分:0)

你可能对JoinBlock如何工作有错误的理解 - 由于某种原因你认为它将从第二个源的第一个元素返回第一个元素的所有元素,这是错误的。它作为zip操作 - 对于每个输入序列,它创建具有相应项的元组:

3  2  1
6  -  -

所以,你应该发布额外的两个6来获得你需要的结果,或者(如果你真的需要笛卡尔输入的产品)自己实现它,因为TPL Dataflow不包含任何结果这种情况的解决方案。

PS:不要将snake_casing用于C#中的变量,而是使用较低的驼峰案例:firstSourcesecondSource