- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 TPL 数据流处理图像。我收到一个处理请求,从流中读取图像,应用多个转换,然后将生成的图像写入另一个流:
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
(或其他一些上下文对象)传递给跨所有其他 block 的 writerBlock
:
TransformBlock<Request,Tuple<Request,Stream>>
TransformBlock<Tuple<Request,Stream>,Tuple<Request,Image>>
TransformBlock<Tuple<Request,Image>,Tuple<Request,Image>>
...
(这很丑陋),或者有没有办法将第一个 block 链接到最后一个 block (或者概括地说,链接到需要额外数据的 block )?
最佳答案
是的,您几乎需要按照您的描述进行操作,将额外的数据从每个 block 传递到下一个 block 。
但是使用几个辅助方法,您可以使这变得更加简单:
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));
}
签名看起来很吓人,但其实并没有那么糟糕。
此外,您可能希望添加将选项传递给创建的 block 的重载,或采用异步委托(delegate)的重载。
例如,如果您想使用单独的 block 对数字执行某些操作,同时沿途传递原始数字,您可以执行以下操作:
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
或 string
,取决于管道的阶段),“原始”值(总是 int
)被自动传递。在任何时候,您都可以使用通过普通构造函数创建的 block 来访问这两个值(例如示例中的最终 ActionBlock
)。
(那个 BufferBlock
实际上不是必需的,但我添加它是为了更符合您的设计。)
关于c# - TPL 数据流 block 下游如何获取源生成的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14612468/
我正在使用 Jenkins 进行持续集成。我创建了单独的 View ,例如服务器 A 的 View A 、服务器 B 的 View B 等。 每个 View 都会根据服务器的环境属性构建我的项目。 但
我有以下伪代码: var queue = new BufferBlock(new DataflowBlockOptions { BoundedCapacity = 5 }); var a = new
我想这样做,但是在 Jenkins DSL 中: 如果在某个地方找到了这个,但它不工作: job('ps-first') { steps { shell('echo "landing"') }
我们的 API 中有一个路由(在调用时)会访问另一个第 3 方 API。 例如 HTTP-GET/account/1 这会从我们的数据库返回一些数据,并从.. 说 .. 像 Auth0/Okta/Sa
我是一名优秀的程序员,十分优秀!