我可以在 ConcurrentBag 上使用普通的 foreach 吗?
Can I use a normal foreach on a ConcurrentBag?
在我的代码的并行部分,我将每个线程的结果保存到一个 ConcurrentBag。但是,完成后,我需要遍历每个结果,并通过我的评估算法 运行 它们。普通的 foreach 实际上会遍历所有成员,还是我需要特殊代码?我也考虑过使用队列之类的东西而不是包,但我不知道哪个最好。并行代码末尾的袋子通常只包含 20 件左右的物品。
也就是说,实际上会访问 ConcurrentBag 的所有成员并 运行 foreach?
ConcurrentBag futures = new ConcurrentBag();
foreach(move in futures)
{
// stuff
}
您不需要特殊代码,C# 的 foreach 将调用 "GetEnumerator" which gives you a snapshot:
The items enumerated represent a moment-in-time snapshot of the
contents of the bag. It does not reflect any update to the collection
after GetEnumerator was called.
您可以在 ConcurrentBag 上使用普通的 ForEach,但不会产生任何性能影响。
这类似于在 List 上使用 ForEach。
为了获得更好的性能,请在 ConcurrentBag 上使用 Parallel.Foreach。
Parallel.ForEach(futures,move=> doOperation;);
只有当你想执行多线程操作时才使用 ConcurrentBag。
在我的代码的并行部分,我将每个线程的结果保存到一个 ConcurrentBag。但是,完成后,我需要遍历每个结果,并通过我的评估算法 运行 它们。普通的 foreach 实际上会遍历所有成员,还是我需要特殊代码?我也考虑过使用队列之类的东西而不是包,但我不知道哪个最好。并行代码末尾的袋子通常只包含 20 件左右的物品。
也就是说,实际上会访问 ConcurrentBag 的所有成员并 运行 foreach?
ConcurrentBag futures = new ConcurrentBag();
foreach(move in futures)
{
// stuff
}
您不需要特殊代码,C# 的 foreach 将调用 "GetEnumerator" which gives you a snapshot:
The items enumerated represent a moment-in-time snapshot of the contents of the bag. It does not reflect any update to the collection after GetEnumerator was called.
您可以在 ConcurrentBag 上使用普通的 ForEach,但不会产生任何性能影响。
这类似于在 List 上使用 ForEach。
为了获得更好的性能,请在 ConcurrentBag 上使用 Parallel.Foreach。
Parallel.ForEach(futures,move=> doOperation;);
只有当你想执行多线程操作时才使用 ConcurrentBag。