在 parallel.foreach 范围之外增加计数值
如何增加parallel.foreach 循环范围之外的整数值?同步对并行循环之外的对象的访问的最简单方法是什么?
var count = 0;
Parallel.ForEach(collection, item =>
{
action(item);
// increment count??
}
How can I increment an integer value outside the scope of a parallel.foreach loop? What's is the lightest way to synchronize access to objects outside parallel loops?
var count = 0;
Parallel.ForEach(collection, item =>
{
action(item);
// increment count??
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我喜欢打败死马! :)
从多个线程增加计数的“最轻”方法是:
但正如其他人指出的那样:如果您在 Parallel.ForEach 内执行此操作,那么您可能做错了什么。
我怀疑由于某种原因您正在使用
ForEach
但您需要正在处理的项目的索引(它永远无法与Parallel.ForEach
一起使用)。我很接近吗?为什么需要计数?你想施展哪种巫毒魔法?更新:
如果您的键是
URI
并且值是TAnswer
,那么使用ConcurrentDictionary
似乎是安全的。只要您不尝试使用计数来引用集合中的元素,我就没有看到问题。最后...
如果您需要计数器,请使用 Parallel.For 循环...它会安全地为您递增计数器。
I like to beat dead horses! :)
The "lightest" way to increment the count from multiple threads is:
But as others have pointed out: if you're doing it inside
Parallel.ForEach
then you're probably doing something wrong.I'm suspecting that for some reason you're using
ForEach
but you need an index to the item you're processing (it will never work withParallel.ForEach
). Am I close? Why do you need the count? What sort of VooDoo magic are you trying to do?UPDATE:
You seem to be safe with the
ConcurrentDictionary
if your key is theURI
and the value isTAnswer
. I don't see a problem as long as you don't try to use the count to reference elements in your collection.Finally...
If you need a counter, then use the
Parallel.For
loop... it safely increments the counter for you.以这种方式使用 Interlocked.Increment 方法。
Use Interlocked.Increment method in this way.
Parallel.Foreach 附带了一个额外的 重载 非常适合当您只想对循环内的内容进行计数时的情况。
您可以在循环体中注入线程本地计数变量并像往常一样递增/递减它。这样,您就不会在每个循环周期中进行 InterLocked 调用。相反,在每个并行任务结束时只有一个 Interlocked.Add 调用来汇总总计数。
请注意,使用此方法时,您不应在循环体内使用
totalCount
。如果您的问题需要从循环体内访问totalCount,您必须使用InterLocked.Incerment 方法,如其他答案中所述。Parallel.Foreach comes along with an extra overload that perfectly fits for that kind of scenario when you just want to count things inside the loop.
Into the loop body you can inject a thread local count varialble and increment/decrement it as usual. This way you do not have an InterLocked call in every loop cycle. Instead there is just one Interlocked.Add call at the end of each parallel Task summing up totalCount.
Note that with this method you should not use
totalCount
from within the loop body. If your problem requires to access totalCount from within the loop body you have to use the InterLocked.Incerment method as describe in other answers.使用
Interlocked.Increment
。我不会在并行 foreach 内增加事物(当然,除非您使用 Interlocked.Increment 或其他一些锁定机制)。那不是它的目的。并行 foreach 应该仅与在共享状态下不会产生副作用的操作一起运行。在并行 foreach 中增加一个值将导致您很可能试图避免的问题。
Use
Interlocked.Increment
.I wouldn't increment things inside a parallel foreach (unless, of course, you're using Interlocked.Increment or some other locking mechanism). That's not what it's for. The Parallel foreach should be run only with actions that cause no side effects in shared state. To increment a value in a parallel foreach will cause the very problem you're more than likely trying to avoid.