【发布时间】: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<Task>并且您忽略了内部任务。由于不应该有任何理由明确等待handleFile,我将只使用return resultHandler.Completion;。 -
编译代码以获得完整的示例。
-
@svick 更新了问题。也使用你的第一个建议。现在可以工作了*
标签: c# async-await system.reactive