我在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
时,会出现丢失/重复的项目
知道我做错了吗?
答案 0 :(得分:1)
我在发现问题时回答了我自己的问题:
在将项目发送到BroadCastBlock
之前,从并发集合中读取(ref类型)项目,更新,然后发送。因此,有时候下一个项目已经从集合中读取并更新,而前一个项目仍然指向同一个现在正在更新的对象。简而言之,这导致了BroadCastBlock
中已有项目的问题。在BroadCastBlock
克隆之后,但在输入队列中的项目之前没有问题。
我必须先执行Quote对象的深层副本,然后才能通过Post或SendAsync
将其发送到广播模块。