简体   繁体   English

TPL 数据流:为什么会出现以下阻塞?

[英]TPL Dataflow: Why is the following blocking?

Why is as a call to Run() blocking and doesn't return?为什么作为对Run()的调用阻塞并且不返回?

It correclty prints the following output, which makes sense.它正确打印以下输出,这是有道理的。 As I have initialized the BatchBlock() with a size of 170 and create 200 volapoint objects.因为我已经初始化了大小为 170 的BatchBlock()并创建了 200 个 volapoint 对象。 But why does it not return?但是为什么不返回呢?

ConvertToVolaSurface 
ConvertToVolaSurface 
CalculateStrangles
CalculateStrangles

This is the code snippet i am working with这是我正在使用的代码片段

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

Your last block is a TransformBlock , transform blocks have an output buffer that must be empty for them to Complete .你的最后一个块是一个TransformBlock ,转换块有一个输出缓冲区,必须为空才能Complete Change your last block to an ActionBlock and await it's completion to not block the calling thread.将您的最后一个块更改为ActionBlockawait它完成以不阻塞调用线程。

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

Now if CalculateStrangles(x) is returning something then you need to link that last transform block to something else otherwise you'll never complete.现在,如果CalculateStrangles(x)正在返回某些内容,那么您需要将最后一个转换块链接到其他内容,否则您将永远无法完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM