TransformManyBlockTInput TOutput

(SelectMany,1-m:这个映射的结果是扁平的,就像 LINQ 的 SelectMany 一样)

TransformManyBlock <TInput,TOutput>与 TransformBlock <TInput,TOutput>非常相似。
关键区别在于,TransformBlock <TInput,TOutput>为每个输入生成一个且仅一个输出,而 TransformManyBlock <TInput,TOutput>为每个输入生成任意数量(零个或多个)输出。与 ActionBlock 和 TransformBlock <TInput,TOutput>一样,可以使用委托指定此处理,用于同步和异步处理。

Func <TInput,IEnumerable>用于同步,Func <TInput,Task <IEnumerable >>用于异步。与 ActionBlock 和 TransformBlock <TInput,TOutput>一样,TransformManyBlock <TInput,TOutput>默认为顺序处理,但可以另外配置。

映射委托返回一组项目,这些项目单独插入到输出缓冲区中。

StackOverflow 文档

异步 Web 爬虫

var downloader = new TransformManyBlock<string, string>(async url =>
{
    Console.WriteLine(“Downloading “ + url);
    try 
    { 
        return ParseLinks(await DownloadContents(url)); 
    } 
    catch{}
    
    return Enumerable.Empty<string>();
});
downloader.LinkTo(downloader);

将可枚举扩展为其组成元素

var expanded = new TransformManyBlock<T[], T>(array => array);

通过从 1 到 0 或 1 个元素进行过滤

public IPropagatorBlock<T> CreateFilteredBuffer<T>(Predicate<T> filter)
{
    return new TransformManyBlock<T, T>(item =>
        filter(item) ? new [] { item } : Enumerable.Empty<T>());
}

Stephen Toub 介绍 TPL 数据流