TPL Dataflow,数据块收到第一项时的通知
Posted
技术标签:
【中文标题】TPL Dataflow,数据块收到第一项时的通知【英文标题】:TPL Dataflow, notification when data block received first item 【发布时间】:2013-04-19 09:30:10 【问题描述】:我想知道在输入缓冲区中接收到第一项或在数据块中处理时是否可以订阅一次性通知。我知道我可以在数据块中设置一个标志,但这会产生开销,因为它会运行检查每个新项目的标志。我的数据块处理数百万个项目,因此这个标志增加了不必要的开销。
有没有更好的方法来通知第一个传入的项目?
【问题讨论】:
也许将输入缓冲区连接到BroadcastBlock
,然后它将链接到您的主数据流和WriteOnceBlock<T>
? WriteOnceBlock
只会被写入一次(第一项)...
你真的是说检查单个bool
是不必要的开销吗?我不信。你试过测量这个吗?
嗯,绝对是个好主意,使用 WriteOnceBlock。无论如何我都使用广播块,所以应该可以。我想我不必处理随后被拒绝的消息,因为项目是通过广播块流式传输的,对吗?
@svick,我有并且当我迭代大约 1700 万条消息时(数据块处理这些消息的批次,但在内部每个批次都被迭代。)在每次运行时,任何 if 条件都会增加开销。现在人们可以争论它是否重要。我测量了它,如果我能在完整的运行中减少 200-500 毫秒,那么它是值得的。
@svick,但我知道您可能指向的地方,可能是我查看了错误的技术实现,如果延迟/吞吐量如此重要,我应该寻找 C++ 解决方案?
【参考方案1】:
您可以尝试使用 MaxMessages=1 创建一个链接到处理通知的块。发送一条消息后,此链接将被删除。
【讨论】:
但是对于普通块,这意味着只有这个块会收到通知,普通目标不会。 嗯,你是对的。您可以让通知块将消息传递给常规目标,但这可能意味着消息被重新排序。或者你可以使用广播块来解决这个问题,在这种情况下应该已经存在。【参考方案2】:(我知道这已经晚了 11 个月......但我正在回答,希望有人能告诉我为什么这不是一个好主意。)
您有一个特定的块 X,您想知道它何时收到第一条消息。它有一个上游块。在上游块和块 X 之间插入一个 TransformBlock,用 MaxMessages=1 将其与上游块链接,以便在收到第一条消息时立即取消链接。这也阻塞了上游块。插入的 TransformBlock 的 Func 在其委托中做了 3 件事:
-
是否会通知您“已收到第一个块”。
将其后继区块 X 链接到上游区块。
返回其参数不变以传递给块 X。
换句话说......插入的块接受并传递第一个数据项,并从数据流中拼接出来。
【讨论】:
以上是关于TPL Dataflow,数据块收到第一项时的通知的主要内容,如果未能解决你的问题,请参考以下文章
使用 TPL-Dataflow 进行聚合和连接(内、外、左……)?
TPL Dataflow,Post() 和 SendAsync() 之间的功能区别是啥?