我在 BroadcastBlock
中使用了一个 TPL Dataflow
,它链接到 ActionBlocks
。但是,我在我的代码中找不到错误。我通过 BroadcastBlock
将项目发布到 SendAsync
,当我在 ActionBlocks
中打印项目时,我发现有些丢失了,而有些则是重复的。我跟踪处理项目的顺序,因此发现只有在项目丢失前一个或后续项目时才会重复(通过 Actionblock
馈送到相同的 LinkTo
)。我不知道发生了什么。以下是我的几个相关代码片段:
这里是 BroadCastBlock
的实例化:
buffer = new BroadcastBlock<Quote>(quote => quote);
这是我如何链接到操作块:
//Filter for incoming quotes
Predicate<Quote> quoteBroadCastFilter = new Predicate<Quote>(newQuote =>
{
if (symbol.symbolID == newQuote.symbol.symbolID)
{
return true;
}
else
{
return false;
}
});
//Link Strategy up to BroadCastBlocks
buffer.LinkTo<Quote>(newStrategy.GetStrategyQuoteBuffer(), new DataflowLinkOptions { PropagateCompletion = true }, quoteBroadCastFilter);
这是我向
BroadCastBlock
提交项目(报价)的方式:buffer.SendAsync(quote);
问题是,当我在通过
SendAsync
发送之前打印出跟踪信息时,一切看起来都很好。当我在 ActionBlock
链接的 BroadCastBlock
中打印相同的信息时,我观察到不常见的错误。我注意到当项目非常快速地提供给 BroadCastBlock
时会发生丢失/重复的项目(通过 API 的 EventHandler
)知道我做错了什么吗?
最佳答案
我在发现问题时回答了我自己的问题:
在项目发送到 BroadCastBlock
之前,项目(ref 类型)从并发集合中读取,更新,然后发送。所以,有时下一个项目已经从集合中读取并更新,而前一个项目仍然指向现在正在更新的同一个对象。简而言之,这导致了 BroadCastBlock
中已有项目的问题。发布 BroadCastBlock
克隆后没有问题,但之前输入队列中的项目没有问题。
在通过 Post 或 SendAsync
将 Quote 对象发送到广播块之前,我必须执行它的深层复制。
关于c# - BroadcastBlock 未按预期工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13175860/