簡體   English   中英

在一個 JoinBlock 中,當另一個 Target 被填充時接收一個 Target

[英]In a JoinBlock, receive a Target when the other Target is filled

我將 JoinBlock 連接到 WriteOnceBlock 和 BufferBlock 以填充目標 1 和 2。我的目標是每次 JoinBlock 收到來自 BufferBlock 的消息時,它還請求 WriteOnceBlock 持有的值。

我的第一個猜測是我可以將 ContinueWith 委托添加到 Target2 Completion 事件,但這不太正確 - 我需要附加到似乎不存在的 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();
    }

期望的輸出:

我收到了 int 3 和字符串 String1。

我收到了 int 3 和字符串 String2。

我收到了 int 3 和字符串 String3。

我收到了 int 3 和字符串 String4。

實際輸出:

我收到了 int 3 和字符串 String1。

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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM