BlockingCollection with Parallel.For 挂起? [英] BlockingCollection with Parallel.For hangs?

查看:74
本文介绍了BlockingCollection with Parallel.For 挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 BlockingCollection 以试图更好地理解它们,但我正在努力理解为什么当我使用 Parallel 时我的代码在完成处理我的所有项目时挂起.对于

I'm playing around with BlockingCollection to try to understand them better, but I'm struggling to understand why my code hangs when it finishes processing all my items when I use a Parallel.For

我只是给它添加了一个数字(制作人?):

I'm just adding a number to it (producer?):

var blockingCollection = new BlockingCollection<long>();

Task.Factory.StartNew(() =>
{
    while (count <= 10000)
    {
        blockingCollection.Add(count);
        count++;
    }
});

然后我正在尝试处理(消费者?):

Then I'm trying to process (Consumer?):

Parallel.For(0, 5, x => 
{
    foreach (long value in blockingCollection.GetConsumingEnumerable())
    {
        total[x] += 1;
        Console.WriteLine("Worker {0}: {1}", x, value);
    }
});

但是当它完成处理所有数字时,它只是挂在那里?我做错了什么?

But when it completes processing all the numbers, it just hangs there? What am I doing wrong?

此外,当我将 Parallel.For 设置为 5 时,是否意味着它正在 5 个单独的线程上处理数据?

Also, when I set my Parallel.For to 5, does it mean it's processing the data on 5 separate thread?

推荐答案

顾名思义,对 BlockingCollection 的操作会在他们无能为力时阻塞,这包括 GetConsumingEnumerable().

As its name implies, operations on BlockingCollection<T> block when they can't do anything, and this includes GetConsumingEnumerable().

这样做的原因是集合无法判断您的生产者是否已经完成,或者只是忙于生产下一个项目.

The reason for this is that the collection can't tell if your producer is already done, or just busy producing the next item.

您需要做的是通过调用 CompleteAdding().例如:

What you need to do is to notify the collection that you're done adding items to it by calling CompleteAdding(). For example:

while (count <= 10000)
{
    blockingCollection.Add(count);
    count++;
}

blockingCollection.CompleteAdding();

这篇关于BlockingCollection with Parallel.For 挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆