如何用TPL Dataflow创建单输入多输出的TransformBlock?
解决TPL Dataflow中单个输入生成多个输出的问题
嗨,我完全懂你的困扰!你现在用的TransformBlock是一对一的转换组件,它的设计就是一个输入对应一个输出,所以你没法直接在里面把多个URL逐个推送到输出栈。不过TPL Dataflow专门提供了适合这种“一对多”场景的块——TransformManyBlock,它正好能满足你的需求!
具体修改方案
你只需要把原来的TransformBlock换成TransformManyBlock,同时调整你的转换方法,让它直接返回URL的集合即可。TransformManyBlock会自动帮你把集合里的每个元素单独发送到输出队列,后续的块就能逐个处理每个URL了。
修改后的代码如下:
首先调整LoadUrl方法,让它返回URL的集合:
private async Task<IEnumerable<Uri>> LoadUrl(IUrlLoaderSettings loaderSettings) { IUrlLoader newLoader = CreateSeedLoader(loaderSettings); // 直接返回加载到的URL列表,TransformManyBlock会自动拆分每个元素 return await newLoader.LoadAsync().ConfigureAwait(false); }
然后创建TransformManyBlock替代原来的TransformBlock:
TransformManyBlock<IUrlLoaderSettings, Uri> loaderBlock = new TransformManyBlock<IUrlLoaderSettings, Uri>(loaderSettings => LoadUrl(loaderSettings));
额外说明
如果之后你遇到需要更灵活的发送场景(比如边加载URL边发送,不需要等全部加载完),也可以用ActionBlock配合目标块的SendAsync方法来实现,但对于你当前的需求,TransformManyBlock是最简洁高效的方案,它已经帮你封装了枚举集合并逐个发送的逻辑,完全不需要你手动循环处理。
这样调整后,每个IUrlLoaderSettings对象加载出的所有URL都会被单独推送到输出栈,后续的块就能按你的预期逐个处理每个URL啦!
内容的提问来源于stack exchange,提问作者João Gonçalves
相关产品推荐
相关产品推荐

