В JoinBlock, получите цель, когда другая цель заполнена - PullRequest
0 голосов
/ 30 августа 2018

Я подключаю JoinBlock к WriteOnceBlock и BufferBlock для заполнения целей 1 и 2. Моя цель состоит в том, чтобы каждый раз, когда JoinBlock получал сообщение от BufferBlock, он также запрашивал значение, которое содержит WriteOnceBlock.

Моим первым предположением было то, что я мог бы добавить делегата ContinueWith к событию Завершение Target2, но это не совсем правильно - мне нужно присоединиться к чему-то вроде события 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 и строку String1.

Я получил int 3 и строку String2.

Я получил int 3 и строку String3.

Я получил int 3 и строку String4.

Фактический объем производства:

Я получил int 3 и строку String1.

1 Ответ

0 голосов
/ 30 августа 2018

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.
...