简体   繁体   English

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

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

I'm connecting a JoinBlock to a WriteOnceBlock and a BufferBlock to fill Targets 1 and 2. My goal is that every time the JoinBlock receives a message from the BufferBlock , it also requests the value that the WriteOnceBlock is holding.我将 JoinBlock 连接到 WriteOnceBlock 和 BufferBlock 以填充目标 1 和 2。我的目标是每次 JoinBlock 收到来自 BufferBlock 的消息时,它还请求 WriteOnceBlock 持有的值。

My first guess was that I could add a ContinueWith delegate to the Target2 Completion event, but that's not quite right - I need to attach to something like a Filled event that doesn't seem to exist.我的第一个猜测是我可以将 ContinueWith 委托添加到 Target2 Completion 事件,但这不太正确 - 我需要附加到似乎不存在的 Filled 事件之类的东西。

I also tried using the join block in non-greedy mode as a last-ditch effort, but that didn't change the output.我还尝试在非贪婪模式下使用 join 块作为最后的努力,但这并没有改变输出。

Am I missing something obvious here?我在这里遗漏了一些明显的东西吗?

Example:例子:

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

Desired output:期望的输出:

I received int 3 and string String1.我收到了 int 3 和字符串 String1。

I received int 3 and string String2.我收到了 int 3 和字符串 String2。

I received int 3 and string String3.我收到了 int 3 和字符串 String3。

I received int 3 and string String4.我收到了 int 3 和字符串 String4。

Actual output:实际输出:

I received int 3 and string String1.我收到了 int 3 和字符串 String1。

The JoinBlock isn't the right choice here although it does seem like the perfect fit. JoinBlock在这里不是正确的选择,尽管它看起来很合适。 The WriteOnceBlock , as you've found, only offers it's value once.正如您所发现的, WriteOnceBlock只提供一次它的价值。 However, you can read that value many times.但是,您可以多次读取该值。 With this you can use a TransformBlock to get the behavior your looking for.有了这个,您可以使用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;
    }
}

Outputs:输出:

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.

相关问题 XmlDataProvider用数据填充目标控件时如何在代码背后知道 - How to know in codebehind when XmlDataProvider has filled target controll with data 标签目标接收值意味着什么? - What does it mean for a label target to receive a value? TabContainer中的CascadingDropDown和其他标签中的Target - CascadingDropDown in TabContainer and Target in other Tab 调用SetPassword时,我收到错误消息:“调用的目标引发了异常。” - When invoking SetPassword i receive the error: “Exception has been thrown by the target of an invocation.” 如何针对您自己以外的所有其他玩家? - How to target all other players other than yourself? 使用纹理作为渲染目标时的大小限制 - Size limitation when using a texture as a render target 目标框架为 4.0 时的 System.BadImageFormatException - System.BadImageFormatException when target framework is 4.0 XNA什么时候放弃渲染目标内容? - When does XNA discard Render Target contents? Visual Studio - 多目标时更改目标框架 - Visual Studio - Change target framework when multitargeting 当目标是ImageBrush.ImageSource时,TemplateBinding失败 - TemplateBinding fails when the target is an ImageBrush.ImageSource
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM