【问题标题】:How to process remaining data in the BlockingCollection<> when CompleteAdding() has been called调用 CompleteAdding() 时如何处理 BlockingCollection<> 中的剩余数据
【发布时间】:2021-04-16 11:55:51
【问题描述】:

BlockingCollection&lt;&gt; 在收到来自CompleteAdding() 方法的调用时忽略处理底层队列中的剩余数据。下面的代码,是消费者方法的一部分:

while (blockingCollection.TryTake(out item Item))
{
    //Do something with item.
}

相反,我想将其更改为处理所有剩余项目 AFTER 生产者问题 CompleteAdding() 方法,然后 ONLY THEN 从循环。

【问题讨论】:

    标签: c# multithreading .net-core concurrency producer-consumer


    【解决方案1】:

    不是使用BlockingCollection&lt;T&gt;的正确方法:

    while (blockingCollection.TryTake(out item Item))
    {
        // Do something with item
    }
    

    上述循环随时退出,blockingCollection 暂时没有项目。正确的方法是枚举GetConsumingEnumerable()

    foreach (var item in blockingCollection.GetConsumingEnumerable())
    {
        // Do something with item
    }
    

    blockingCollection 被标记为CompleteAdding 并且所有可用项目都已处理时,上述循环退出。如果在任何时候blockingCollection 暂时为空,则循环会阻塞当前线程,同步等待新项目或CompleteAdding() 信号。

    下面介绍了一个更专业的循环变体。在不活动的情况下,它每隔几秒钟记录一条消息,以便您知道消费者没有死,而只是处于空闲状态。

    while (true)
    {
        while (blockingCollection.TryTake(out item Item, TimeSpan.FromSeconds(10)))
        {
            // Do something with item
        }
        if (blockingCollection.IsCompleted) break;
    
        // Log a heartbeat
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-22
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      相关资源
      最近更新 更多