Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel.ForEach with adding to list

I'm trying to run multiple functions that connect to a remote site (by network) and return a generic list. But I want to run them simultaneously.

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 see it, multiple insertions to 'results' may happend at the same time... Which may crash my application.

How can I avoid this?

like image 885
shaharmor Avatar asked Nov 03 '11 20:11

shaharmor


People also ask

Does parallel ForEach wait for completion?

You don't have to do anything special, Parallel. Foreach() will wait until all its branched tasks are complete. From the calling thread you can treat it as a single synchronous statement and for instance wrap it inside a try/catch.

How do you continue in parallel ForEach?

ForEach() is meant to be a parallel Asynchronous operation, so there is nothing to continue; or break; as theoretically all _dongles. GetArray() members should be accessed at the same instance, thus having a break; or especially a continue; won't be logical in the first place. You should just use return; that's all.

Is Linq ForEach parallel?

The linq parallel foreach will partition your collection and work on it at the same time, which you also need to take into account making sure your this. Update can work with multiple users without messing up .

Is parallel ForEach faster than ForEach?

The execution of Parallel. Foreach is faster than normal ForEach.


2 Answers

You can use a concurrent collection.

The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used in place of the corresponding types in the System.Collections and System.Collections.Generic namespaces whenever multiple threads are accessing the collection concurrently.

You could for example use ConcurrentBag since you have no guarantee which order the items will be added.

Represents a thread-safe, unordered collection of objects.

like image 133
Mark Byers Avatar answered Sep 28 '22 03:09

Mark Byers


//In the class scope: Object lockMe = new Object();      //In the function lock (lockMe) {          results.AddRange(tmpResults); } 

Basically a lock means that only one thread can have access to that critical section at the same time.

like image 42
Haedrian Avatar answered Sep 28 '22 04:09

Haedrian