views:

337

answers:

2

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??
}
+2  A: 

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.

David Morton
agree. My question is why he needs that count. Check if all actions are finished? There should be better way to sync that.
Kai Wang
+5  A: 

I like to beat dead horses! :)

The "lightest" way to increment the count from multiple threads is:

Interlocked.Increment(ref count);

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 with Parallel.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 the URI and the value is TAnswer. 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.

Lirik
Fetching thousands of web pages using multiple threads given a list of starting uris. I'm interested in seeing how many of them have been processed so far. Using a concurrent dictionaries seems to cover my needs actually: <code>ConcurrentDictionary<Uri, TAnswer></code>. Then I can use the <code>Count</code> property of the dictionary. Still there are some cases where processing a sequence of items does not produce any results like fetched html documents. In such simple cases I thought I could use a just a variable with proper synchronization and wanted to know how to do it.
Cetin Sert