在JoinBlock中,当另一个目标被填充时接收一个目标

时间:2018-08-30 07:10:08

标签: c# .net tpl-dataflow

我正在将JoinBlock连接到WriteOnceBlock和BufferBlock来填充目标1和2。我的目标是,每次JoinBlock收到来自BufferBlock的消息时,它还会请求WriteOnceBlock保持的值。

我的第一个猜测是我可以向Target2 Completion事件添加一个ContinueWith委托,但这并不完全正确-我需要附加到一个似乎不存在的Filled事件之类的东西。

我还尝试了在非贪婪模式下使用join块作为最后的努力,但这并没有改变输出。

我在这里缺少明显的东西吗?

示例:

static void Main(string[] args)
    {
        var writeOnceBlockTest = new WriteOnceBlock<int>(i => i);
        var queueBlockTest = new BufferBlock<string>();
        var joinBlockTest = new JoinBlock<int, string>();
        var actionBlockTest = new ActionBlock<System.Tuple<int, string>>(tuple => Console.WriteLine($"I received int {tuple.Item1} and string {tuple.Item2}."));

        writeOnceBlockTest.LinkTo(joinBlockTest.Target1);
        queueBlockTest.LinkTo(joinBlockTest.Target2, new DataflowLinkOptions{PropagateCompletion = true});
        joinBlockTest.LinkTo(actionBlockTest, new DataflowLinkOptions { PropagateCompletion = true });

        writeOnceBlockTest.Post(3);
        queueBlockTest.Post("String1");
        queueBlockTest.Post("String2");
        writeOnceBlockTest.Post(4);
        writeOnceBlockTest.Post(5);
        queueBlockTest.Post("String3");
        queueBlockTest.Post("String4");
        queueBlockTest.Complete();
        Console.ReadLine();
    }

所需的输出:

  

我收到了整数3和字符串String1。

     

我收到了整数3和字符串String2。

     

我收到了整数3和字符串String3。

     

我收到了整数3和字符串String4。

实际输出:

  

我收到了整数3和字符串String1。

1 个答案:

答案 0 :(得分:1)

JoinBlock虽然看起来很合适,但在这里并不是正确的选择。正如您所发现的,WriteOnceBlock仅提供一次它的价值。但是,您可以多次读取该值。这样,您可以使用TransformBlock来获取您想要的行为。

public class JoinFlow
{
    [Test]
    public async Task TestWriteOnceBlock()
    {
        var writeOnceBlockTest = new WriteOnceBlock<int>(i => i);
        var queueBlockTest = new BufferBlock<string>();
        var transformBlockTest = new TransformBlock<string, Tuple<int, string>>(async str => Tuple.Create(await writeOnceBlockTest.ReceiveAsync(), str));
        var actionBlockTest = new ActionBlock<Tuple<int, string>>(tuple => Console.WriteLine($"I received int {tuple.Item1} and string {tuple.Item2}."));

        queueBlockTest.LinkTo(transformBlockTest, new DataflowLinkOptions { PropagateCompletion = true });
        transformBlockTest.LinkTo(actionBlockTest, new DataflowLinkOptions { PropagateCompletion = true });

        writeOnceBlockTest.Post(3);
        queueBlockTest.Post("String1");
        queueBlockTest.Post("String2");
        writeOnceBlockTest.Post(4);
        writeOnceBlockTest.Post(5);
        queueBlockTest.Post("String3");
        queueBlockTest.Post("String4");
        queueBlockTest.Complete();
        await actionBlockTest.Completion;
    }
}

输出:

I received int 3 and string String1.
I received int 3 and string String2.
I received int 3 and string String3.
I received int 3 and string String4.