Поток данных TPL: Почему следующая блокировка? - PullRequest
0 голосов
/ 25 января 2019

Почему при вызове Run() блокируется и не возвращается?

Это корректно печатает следующий вывод, который имеет смысл.Как я инициализировал BatchBlock() размером 170 и создал 200 объектов volapoint.Но почему он не возвращается?

ConvertToVolaSurface 
ConvertToVolaSurface 
CalculateStrangles
CalculateStrangles

Это фрагмент кода, с которым я работаю

class Pipeline
{
    public void Run()
    {
        // Grouping block - Collect vola points until vola surface is full 
        var batchBlock1 = new BatchBlock<VolaPoint>(170);

        // Execution block - Convert vola points to surface
        var transformBlock0 = new TransformBlock<VolaPoint[], VolaSurface>(x => this.ConvertToVolaSurface(x));

        // Execution block - Calculate strangles 
        var transformBlock1 = new TransformBlock<VolaSurface, VolaSurface>(x => this.CalculateStrangles(x));

        var linkOptions = new DataflowLinkOptions()
        {
            PropagateCompletion = true
        };

        batchBlock1.LinkTo(transformBlock0, linkOptions);
        transformBlock0.LinkTo(transformBlock1, linkOptions);

        for (int i = 0; i <= 200; i++)
        {
            batchBlock1.Post(new VolaPoint());
        }

        batchBlock1.Complete();

        transformBlock1.Completion.Wait();
    }

    private VolaSurface ConvertToVolaSurface(VolaPoint[] volapoints)
    {
        Debug.WriteLine("ConvertToVolaSurface");

        return new VolaSurface();
    }

    private VolaSurface CalculateStrangles(VolaSurface volaSurface)
    {
        Debug.WriteLine("CalculateStrangles");

        return volaSurface;
    }
}   

1 Ответ

0 голосов
/ 25 января 2019

Ваш последний блок - TransformBlock, у блоков преобразования есть выходной буфер, который должен быть пустым для них Complete. Измените свой последний блок на ActionBlock и await, чтобы завершить, чтобы не блокировать вызывающий поток.

public async Task Run()
{
    // Grouping block - Collect vola points until vola surface is full 
    var batchBlock1 = new BatchBlock<VolaPoint>(170);

    // Execution block - Convert vola points to surface
    var transformBlock0 = new TransformBlock<VolaPoint[], VolaSurface>(x => this.ConvertToVolaSurface(x));

    // Execution block - Calculate strangles 
    var actionBlock1 = new ActionBlock<VolaSurface>(x => this.CalculateStrangles(x));

    var linkOptions = new DataflowLinkOptions()
    {
        PropagateCompletion = true
    };

    batchBlock1.LinkTo(transformBlock0, linkOptions);
    transformBlock0.LinkTo(actionBlock1, linkOptions);

    for (int i = 0; i <= 200; i++)
    {
        batchBlock1.Post(new VolaPoint());
    }

    batchBlock1.Complete();

    await actionBlock1.Completion;
}

Теперь, если CalculateStrangles(x) возвращает что-то, вам нужно связать этот последний блок преобразования с чем-то другим, иначе вы никогда не завершите.

...