BroadcastBlock没有按预期工作

时间:2012-11-01 11:14:49

标签: c# concurrency task-parallel-library tpl-dataflow

我在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时,会出现丢失/重复的项目

知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

我在发现问题时回答了我自己的问题:

在将项目发送到BroadCastBlock之前,从并发集合中读取(ref类型)项目,更新,然后发送。因此,有时候下一个项目已经从集合中读取并更新,而前一个项目仍然指向同一个现在正在更新的对象。简而言之,这导致了BroadCastBlock中已有项目的问题。在BroadCastBlock克隆之后,但在输入队列中的项目之前没有问题。

我必须先执行Quote对象的深层副本,然后才能通过Post或SendAsync将其发送到广播模块。