Search code examples
c#multithreadingasp.net-corethread-safetyparallel.foreach

Parallel.ForEach in Web API


Does the following code run without any problems or side effects?

var result = new List<MyTpe>();
Parallel.ForEach(items, i =>
{
   // make DB-request 
   ..
   result.Add(otherResult);
}

I'm not using a Dictionary, so I do not have any duplicate keys. I just add entries to the List. So, I don't need to use a concurrent collection, do I?


Solution

  • Your code is not thread safe, so, yes, there could be problems such as overwriting list entries. Also, Add could cause the list to resize. Imagine if two threads simultaneously triggered that.

    You can place a lock around your accesses to the list, or even better use a concurrent collection such as ConcurrentBag if you don't care about order.

    Another way to do this is to allocate an array sized to the degree of parallelism on the Parallel.ForEach and then (safely) put the results into the respective slot. Finally, you'd then assemble the results after the loop.

    Something like

    // this example assumes parallelism is 4
    var result = new List<MyTpe>[4];
    Parallel.ForEach(items, i =>
    {
       var localResult = new List<MyType>();
       // make DB-request 
       localResult.Add(otherResult);
       ...
       // n passed in somehow (check the overloads of ForEach()
       result[n] = localResult;
    }
    
    ...
    var finalResult = new List<MyType>();
    foreach (var r in result)
        finalResult.AddRange(r);