我正在学习数据流基础知识. 下面是一个代码示例,它看起来是正确的,但不起作用. 它不是返回结果整数值,而是冻结. 在我的理解中,这是因为补全不是在块之间传播的.

    public static int Process(int value)
    {
        var multiplyBlock = new TransformBlock<int, int>(item => item * 2);
        var subtractBlock = new TransformBlock<int, int>(item => item - 2);

        var options = new DataflowLinkOptions() { PropagateCompletion = true };
        multiplyBlock.LinkTo(subtractBlock, options);

        multiplyBlock.Post(value);

        multiplyBlock.Complete();
        subtractBlock.Completion.Wait(); // <--- code freezes here

        return subtractBlock.Receive();
    }

你能帮我了解一下遗漏了什么吗?

推荐答案

当upstream multiplyBlock.Completion完成时,自动调用subtractBlock.Complete()(因为PropagateCompletion = true ).到那时,subtractBlock.Completion不会立即完成.当以下两个条件均为真时,它将完成:

  1. subtractBlock的输入缓冲区中的所有项目都已处理完毕.
  2. subtractBlock的输出缓冲区中的所有项目都已被下游的一个块接受.

换句话说,TransformBlock<TInput, TOutput>的输入和输出缓冲区都必须为空,否则该块将永远不会完成.在本例中,块的输出缓冲区不会清空,因为该块没有链接到任何东西.您可以通过将其链接到NullTarget或将其替换为ActionBlock<TInput>来解决此问题.

顺便说一句,目前TPL Dataflow库有一个错误,在非常特殊和罕见的情况下,可能会导致管道永远无法完成.你可以找到这个错误here的演示.这个漏洞一直存在,不太可能在短期内得到解决.

Csharp相关问答推荐

在Microsoft XNA框架(MonoGame)中旋转相机

使用C#中的Shape API从Azure目录获取所有用户

无法从具有一对多关系的C#类中使用Swagger创建记录

为什么我不能更改尚未设置的模拟对象属性的值?

如何从泛型方法返回一个可为空的T,其中T:notnull?

ASP.NET核心结果.文件vs结果.流

一小时后,自定义缓存停止在App Insight中保存

为什么SignalR在每个Blazor服务器应用程序启动时最多启动8个服务器?

Azure DEVOPS找不到定制的Nuget包

Blazor服务器端的身份验证角色

在实体框架中处理通用实体&S变更跟踪器

当前代码Cosmos DB 3.37.1:PartitionKey key key mismatch exception

如何允许数组接受多个类型?

C#无法将.csv列转换为用于JSON转换的列表

如何阻止可传递依赖项出现在项目中

如何更改Datagridview行标题

C#-如何将int引用获取到byte[]

我可以阻止类型上的Object.ToString()吗?

如何在.NET8中使用Blazor Web App(WebAssembly)托管服务器端控制器?

在Blazor中动态隐藏MUD文本