Transformblock 没有发布到 Actionblock

Transformblock not posting to Actionblock

我对整个主题相当陌生,作为培训,我决定利用 ReactiveExtensions 和 async/await 提供的功能编写一个 GREP 克隆。

以下代码不会将在 transformblock 中转换的项目传播到 resultHandler。

    var flowOptions = new DataflowLinkOptions {PropagateCompletion = true};

    ....

    private static Task _searchTermInFilesAsync(Options options, 
                                                CancellationToken token,
                                                ExecutionDataflowBlockOptions executionOptions, 
                                                ActionBlock<FileSearcherResult> resultHandler,
                                                DataflowLinkOptions flowOptions)
    {
        var enumerator = new TransformManyBlock<Options, FileData>(o => _enumerateFiles(o).TakeWhile(_ => !token.IsCancellationRequested), executionOptions);

        var handleFile = new TransformBlock<FileData, FileSearcherResult>(async data => await _handleFile(options, data), executionOptions);

        enumerator.LinkTo(handleFile, flowOptions);

        handleFile.LinkTo(resultHandler, flowOptions, result => result != null);

        enumerator.Post(options);
        enumerator.Complete();

        return resultHandler.Completion;
    }

我有一个类似的方法,效果几乎一样,唯一的区别是没有转换块(另一种方法仅用于枚举名称模式的文件)。两种方法都使用相同的 resultHandler,因此我们可以假设它工作正常。

那么为什么 TransformBlock 不将结果发送到 resultHandler 中?我检查过没有产生空结果。

编辑 显然过滤器有问题。

  handleFile.LinkTo(resultHandler, flowOptions); //, result => result != null);

如果我把它注释掉,就可以了。奇怪的是那里也有 "notnull" 结果。一旦它 returns 为假,过滤器似乎就停止了整个事情。

Strangely there are "notnull" results in there aswell.

这并不奇怪。每个有输出的块都有一个输出 queue。项目将按照它们到达的顺序离开此队列(这也称为 FIFO)。这意味着如果 null 到达并且没有块接收它,处理将停止。

最简单的解决方案是添加一个将接受这些 null 的块,但不对它们执行任何操作:

handleFile.LinkTo(DataflowBlock.NullTarget<FileSearcherResult>(), result => result == null);