Parallel.ForEach added to list

I am trying to run several functions that connect to a remote site (over the network) and return a general list. But I want to run them at the same time.

For example:

public static List<SearchResult> Search(string title) { //Initialize a new temp list to hold all search results List<SearchResult> results = new List<SearchResult>(); //Loop all providers simultaneously Parallel.ForEach(Providers, currentProvider => { List<SearchResult> tmpResults = currentProvider.SearchTitle((title)); //Add results from current provider results.AddRange(tmpResults); }); //Return all combined results return results; } 

As I can see, several simultaneous entries in the "results" can happen ... Which can lead to the failure of my application.

How can i avoid this?

+47
list c # parallel-processing locking
Nov 03 2018-11-11T00:
source share
5 answers
 //In the class scope: Object lockMe = new Object(); //In the function lock (lockMe) { results.AddRange(tmpResults); } 

Basically, locking means that only one thread can access this critical section at the same time.

+35
Nov 03 2018-11-11T00:
source share

You can use a parallel collection .

The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used instead of the corresponding types in the System.Collections and System.Collections.Generic namespaces when multiple threads access the collection at the same time.

You can, for example, use ConcurrentBag , since you have no guarantee which order will be added.

It is a thread safe, disordered collection of objects.

+91
Nov 03 2018-11-11T00:
source share

Parallel collections are new for .Net 4; they are designed to work with new parallel functionality.

See Parallel Collections in the .NET Framework 4 :

Prior to .NET 4, you had to provide your own synchronization mechanisms if multiple threads can access the same shared collection. You needed to lock the collection ...

... [new] classes and interfaces in System.Collections.Concurrent [added in .NET 4] provide a consistent implementation for [...] multi-threaded programming tasks related to common data on threads.

+20
Nov 03 2018-11-11T00:
source share

For those who prefer the code:

 public static ConcurrentBag<SearchResult> Search(string title) { var results = new ConcurrentBag<SearchResult>(); Parallel.ForEach(Providers, currentProvider => { results.Add(currentProvider.SearchTitle((title))); }); return results; } 
+11
Dec 01 '15 at 10:17
source share

This could be summarized using PLINQ AsParallel and SelectMany :

 public static List<SearchResult> Search(string title) { return Providers.AsParallel() .SelectMany(p => p.SearchTitle(title)) .ToList(); } 
+9
Nov 16 '14 at 21:19
source share



All Articles