Jay Nanavaty
Jay Nanavaty

Reputation: 1129

Parallel.ForEach and global variable

If I have code as following:

var dict = new Dictionary<string, NetObject>();
Parallel.ForEach(results, options, result =>                    
{
    var items = parser.Parse(result);
    Parallel.ForEach(items, options, nextObject =>                      
    {
        if (nextObject != null)
        {
            dict[nextObject.Id] = nextObject;
        }
    });
});

The dict is a dictionary defined at method level. My question is, will it cause parallel foreach to work like normal foreach in synchronous manner since it is global object? I do not see any performance difference between normal foreach and parallel once for the code above.

Upvotes: 1

Views: 2489

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

Your code isn't thread-safe. You're mutating a Dictionary<K, V> which isn't a thread-safe data structure. Also, you're most likely over parallelising the loop with both Parallel.ForEach to iterate the inner and outter loop.

Let me suggest a different approach using PLINQ, which doesn't require you to synchronize a global Dictionary. Note you should make sure there are no duplicate keys when doing this (perhaps with an additional .Distinct() call):

results
  .AsParallel()
  .SelectMany(x => parser.Parse(x))
  .Where(x => x != null)
  .ToDictionary(x => x.Id, x => x);

But of course, the most important thing is to benchmark your code to make sure that parallelism is actually increasing performance, and that you're gaining anything from this.

Upvotes: 3

Related Questions