TPL 数据流块下游如何获取源生成的数据?

2024-05-09

我正在使用 TPL Dataflow 处理图像。我收到处理请求,从流中读取图像,应用多次转换,然后将生成的图像写入另一个流:

Request -> Stream -> Image -> Image ... -> Stream

为此,我使用块:

BufferBlock<Request>
TransformBlock<Request,Stream>
TransformBlock<Stream,Image>
TransformBlock<Image,Image>
TransformBlock<Image,Image>
...
writerBlock = new ActionBlock<Image>

问题是最初的Request包含创建结果所需的一些数据Stream以及我当时需要的一些附加信息。我必须通过原件吗Request(或其他一些上下文对象)沿着线到writerBlock像这样跨越所有其他块:

TransformBlock<Request,Tuple<Request,Stream>>
TransformBlock<Tuple<Request,Stream>,Tuple<Request,Image>>
TransformBlock<Tuple<Request,Image>,Tuple<Request,Image>>
...

(这很丑陋),或者有没有办法将第一个块链接到最后一个块(或者概括地说,链接到需要附加数据的块)?


是的,您非常需要执行您所描述的操作,将附加数据从每个块传递到下一个块。

但是使用一些辅助方法,您可以使这变得更简单:

public static IPropagatorBlock<TInput, Tuple<TOutput, TInput>>
    CreateExtendedSource<TInput, TOutput>(Func<TInput, TOutput> transform)
{
    return new TransformBlock<TInput, Tuple<TOutput, TInput>>(
        input => Tuple.Create(transform(input), input));
}

public static IPropagatorBlock<Tuple<TInput, TExtension>, Tuple<TOutput, TExtension>>
    CreateExtendedTransform<TInput, TOutput, TExtension>(Func<TInput, TOutput> transform)
{
    return new TransformBlock<Tuple<TInput, TExtension>, Tuple<TOutput, TExtension>>(
        tuple => Tuple.Create(transform(tuple.Item1), tuple.Item2));
}

这些签名看起来令人畏惧,但实际上并没有那么糟糕。

此外,您可能想要添加将选项传递给创建的块的重载,或采用异步委托的重载。

例如,如果您想使用单独的块对数字执行某些操作,同时传递原始数字,您可以执行以下操作:

var source = new BufferBlock<int>();
var divided = CreateExtendedSource<int, double>(i => i / 2.0);
var formatted = CreateExtendedTransform<double, string, int>(d => d.ToString("0.0"));
var writer = new ActionBlock<Tuple<string, int>>(tuple => Console.WriteLine(tuple));

source.LinkTo(divided);
divided.LinkTo(formatted);
formatted.LinkTo(writer);

for (int i = 0; i < 10; i++)
    source.Post(i);

正如您所看到的,您的 lambda(最后一个除外)仅处理“当前”值(int, double or string,取决于管道的阶段),“原始”值(始终int)自动通过。在任何时候,您都可以使用使用普通构造函数创建的块来访问这两个值(例如最终的ActionBlock在示例中)。

(That BufferBlock实际上并不是必需的,但我添加它是为了更符合您的设计。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TPL 数据流块下游如何获取源生成的数据? 的相关文章

随机推荐