C# TransformBlock не выполняется после вызова функции Complete - PullRequest
0 голосов
/ 11 марта 2020

У меня есть этот фрагмент кода:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });
    var countBytes = new TransformBlock<int, int>(
        new Func<int, int>((x)=> { return 2 * x; }));
    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Completion.ContinueWith(delegate { printResult.Complete(); });
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.ReadKey();
}

Я ожидал, что код TransformBlock

return 2*x

запустится, а затем напечатает результат, но на самом деле ничего печатается. Я установил точку останова внутри функционального объекта

printResult

на Console.WriteLine, но он не был введен.

Почему ничего не печатается, где я ошибся и как исправить это?

1 Ответ

1 голос
/ 11 марта 2020

Вам не хватает параметра, чтобы сказать countBytes, чтобы распространять завершение на связанный блок (попытка использовать ContinueWith () для завершения связанного блока - неправильный способ сделать это).

Также, если вы ничего не публикуете в конвейер, вывод не будет.

Попробуйте вместо этого:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });

    var countBytes = new TransformBlock<int, int>(new Func<int, int>((x) => { return 2 * x; }));

    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Post(1);
    countBytes.Completion.ContinueWith(task => Console.WriteLine("countBytes has completed"));
    printResult.Completion.ContinueWith(task => Console.WriteLine("printResult has completed"));
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.WriteLine("Done");
    Console.ReadLine();
}

Если вы запустите это, вы получите:

2
countBytes has completed
Done
printResult has completed

(Обратите внимание, что вывод «printResult завершен» после «Готово». Это потому, что продолжение запланировано ПОСЛЕ printResult.Completion.)

Если вы закомментируйте new DataflowLinkOptions { PropagateCompletion = true } следующим образом:

countBytes.LinkTo(printResult /*, new DataflowLinkOptions { PropagateCompletion = true } */);

, тогда результат будет:

2
countBytes has completed

Обратите внимание, что «Done» не печатается, потому что printResult.Completion.Wait() никогда не возвращается, если завершение не распространяется на этот блок.

...