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

问题描述 投票:1回答:1

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

我的第一个猜测是我可以在Target2 Completion事件中添加一个ContinueWith委托,但这不太正确 - 我需要附加一些似乎不存在的Filled事件。

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

我错过了一些明显的东西吗?

例:

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();
    }

期望的输出:

我收到了int 3和string String1。

我收到了int 3和string String2。

我收到了int 3和string String3。

我收到了int 3和string String4。

实际产量:

我收到了int 3和string String1。

c# .net tpl-dataflow
1个回答
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.
© www.soinside.com 2019 - 2024. All rights reserved.