C# TransformBlock не запускается даже после вызова «Complete ()» - PullRequest
0 голосов
/ 11 марта 2020

Я получил этот фрагмент кода, пытаясь использовать TransformBlock для запуска выполнения кода, как показано ниже:

public static void Main(string[] args)
{
    var multiplyBlock = new TransformBlock<int, int>(x => x * 2);
    var additionBlock = new TransformBlock<int, int>(x => x + 2);
    multiplyBlock.LinkTo(additionBlock, new DataflowLinkOptions { PropagateCompletion = true });
    multiplyBlock.Post(3);
    additionBlock.Completion.ContinueWith(x => Console.WriteLine(x));

    multiplyBlock.Complete();
    additionBlock.Completion.Wait();
}

Но когда я запускаю этот код, он зависает и ничего не печатает. Я попытался отладить его, я обнаружил, что все строки кода завершены, но в конце функции программа зависает. Так что здесь происходит и как это исправить?

Спасибо.

1 Ответ

3 голосов
/ 11 марта 2020

Вам нужно использовать ActionBlock, чтобы использовать вывод из TransFormBlock, например так:

public static void Main(string[] args)
{
    var multiplyBlock = new TransformBlock<int, int>(x => x * 2);
    var additionBlock = new TransformBlock<int, int>(x => x + 2);
    var outputBlock   = new ActionBlock<int>(Console.WriteLine);

    multiplyBlock.LinkTo(additionBlock, new DataflowLinkOptions { PropagateCompletion = true });
    additionBlock.LinkTo(outputBlock,   new DataflowLinkOptions { PropagateCompletion = true });

    multiplyBlock.Post(3);

    multiplyBlock.Complete();
    outputBlock.Completion.Wait();
}

Если вы просто попытаетесь использовать TransformBlock, ничего не произойдет, потому что нет ничего, что могло бы потреблять все выход.

Подумайте об этом так: TransformBlock имеет вход и выход, поэтому выход должен как-то потребляться. ActionBlock имеет только вход, и он будет вызываться повторно с выходом из TransformBlock. (Это несколько упрощает, но это должно помочь вам разобраться в проводке.)

В приведенном выше примере выход блока умножения связан с входом блока сложения, а выход Блок сложения подключен к входу блока вывода.

Вход в блок умножения должен откуда-то поступать, и здесь он идет от вызова multiplyBlock.Post(3);.

(На самом деле, если вы хотите использовать вывод TransformBlock в явном виде вы можете сделать это, вызвав TransformBlock.Receive() (или один из других методов получения) в al oop для обработки данных, но в этом нет необходимости, так как гораздо проще использовать ActionBlock для использования преобразованных данных .)

Эта документация может быть вам полезна.

...