【问题标题】:Transformblock not posting to ActionblockTransformblock 未发布到 Actionblock
【发布时间】:2016-07-09 22:23:52
【问题描述】:

我对整个主题相当陌生,作为培训,我决定利用 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”结果。一旦它返回false,过滤器似乎停止了整个事情。

【问题讨论】:

  • 你能提供一个minimal reproducible example吗?
  • 另外,这可能与您的问题无关,但您的回报不正确。 ContinueWith() 将返回 Task&lt;Task&gt; 并且您忽略了内部任务。由于不应该有任何理由明确等待handleFile,我将只使用return resultHandler.Completion;
  • 编译代码以获得完整的示例。
  • @svick 更新了问题。也使用你的第一个建议。现在可以工作了*

标签: c# async-await system.reactive


【解决方案1】:

奇怪的是那里也有“notnull”结果。

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

最简单的解决方案是添加一个可以接受这些nulls 的块,但对它们什么都不做:

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

【讨论】:

  • 成功了。我猜我完全误解了这里的工作原理。
猜你喜欢
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 2019-05-01
  • 2012-01-17
  • 1970-01-01
  • 2021-10-07
相关资源
最近更新 更多