BlockingCollection with Parallel.For hangs?
本文关键字:hangs For Parallel with BlockingCollection | 更新日期: 2023-09-27 18:36:09
我正在玩BlockingCollection
以尝试更好地理解它们,但是当我使用Parallel.For
时,我正在努力理解为什么我的代码在完成处理我的所有项目时
我只是在上面添加一个数字(制片人?
var blockingCollection = new BlockingCollection<long>();
Task.Factory.StartNew(() =>
{
while (count <= 10000)
{
blockingCollection.Add(count);
count++;
}
});
然后我正在尝试处理(消费者?
Parallel.For(0, 5, x =>
{
foreach (long value in blockingCollection.GetConsumingEnumerable())
{
total[x] += 1;
Console.WriteLine("Worker {0}: {1}", x, value);
}
});
但是当它完成处理所有数字时,它就挂在那里了?我做错了什么?
另外,当我将 Parallel.For 设置为 5 时,是否意味着它正在处理 5 个独立线程上的数据?
名思义,当BlockingCollection<T>
块上无法执行任何操作时,这包括GetConsumingEnumerable()
。
这样做的原因是,该系列无法判断您的制作人是否已经完成,或者只是忙于制作下一个项目。
您需要做的是通过调用 CompleteAdding()
来通知集合您已完成向其添加项目。例如:
while (count <= 10000)
{
blockingCollection.Add(count);
count++;
}
blockingCollection.CompleteAdding();
GetConsumingEnumerable
方法功能。
如果没有任何项可用或集合为空,则以这种方式枚举集合会阻止使用者线程。
您可以在此处阅读更多相关信息
此外,使用 Parallel.For(0,5)
并不能保证数据将在 5 个单独的线程中处理。这取决于Environment.ProcessorCount
.
另外,当我将 Parallel.For 设置为 5 时,是否意味着它正在处理 5 个独立线程上的数据?
不,引用SO中的先前答案(Parallel.For(Foreach)将创建多少个线程?默认最大并行度?
任务并行库和 PLINQ 的默认调度程序使用 .NET Framework ThreadPool 用于排队和执行工作。在 .NET 中 框架 4,线程池使用由 System.Threading.Tasks.Task 类型,以有效地支持 并行的细粒度并行性(短期工作单元) 任务和查询通常表示。
简而言之,TPL 创建任务,而不是线程。框架决定应该处理多少个线程。